Compare commits
1509 Commits
mandarindu
...
sandbox/ya
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc436734bd | ||
|
|
7e89c102c4 | ||
|
|
cbed16b8b3 | ||
|
|
9faf9148ec | ||
|
|
476e44a689 | ||
|
|
59589d0c4a | ||
|
|
fe291b647e | ||
|
|
a0a23b7f0c | ||
|
|
56a91f139d | ||
|
|
a1b6507e2b | ||
|
|
6679608386 | ||
|
|
0d5ac98d1c | ||
|
|
2b2ee5cdf6 | ||
|
|
1af28f0230 | ||
|
|
108df24d2a | ||
|
|
d9e73a32fc | ||
|
|
efe198fb04 | ||
|
|
a3cff08259 | ||
|
|
aa810c002c | ||
|
|
0acb76d8eb | ||
|
|
b06147de6b | ||
|
|
31dab60888 | ||
|
|
8bf837f153 | ||
|
|
134710af32 | ||
|
|
0594c7f5b1 | ||
|
|
de42ab22bd | ||
|
|
22fda38fa4 | ||
|
|
d4c4724090 | ||
|
|
a4daf360ca | ||
|
|
ac86d3d668 | ||
|
|
5eee90730b | ||
|
|
3fa28d51af | ||
|
|
f67ff4a5b7 | ||
|
|
3ecf31dbdf | ||
|
|
3bd709fafe | ||
|
|
8915eb8e9a | ||
|
|
725f7f9d57 | ||
|
|
b124b243d4 | ||
|
|
831e009970 | ||
|
|
6d6291b119 | ||
|
|
077168bb16 | ||
|
|
d8f83fcfd6 | ||
|
|
73eb764a35 | ||
|
|
8e3766f967 | ||
|
|
abb842d45c | ||
|
|
2cd670d1c8 | ||
|
|
eb66904d7c | ||
|
|
12ca90d383 | ||
|
|
74e230336f | ||
|
|
60be793eb6 | ||
|
|
a8de3c0c89 | ||
|
|
1c1bc94899 | ||
|
|
e0c265e4cb | ||
|
|
57303cb783 | ||
|
|
ec53ba7dad | ||
|
|
3a9e8797c0 | ||
|
|
8dbbcda9c7 | ||
|
|
2a5a3f6bed | ||
|
|
230c24caaf | ||
|
|
464724c4d2 | ||
|
|
53fb766d2a | ||
|
|
3f5a2a8ee2 | ||
|
|
d2fa9fe853 | ||
|
|
d2e11e9705 | ||
|
|
19a95f0e07 | ||
|
|
b171dcb1ee | ||
|
|
da30900381 | ||
|
|
e96c20b14d | ||
|
|
44aac61c13 | ||
|
|
3826383ca1 | ||
|
|
0ea035f8b7 | ||
|
|
a7cfdd9457 | ||
|
|
e9bd26b826 | ||
|
|
e5848dea5a | ||
|
|
ff3f35c16c | ||
|
|
f9c01c7b76 | ||
|
|
b2663a8a67 | ||
|
|
dec16abf7f | ||
|
|
c03268b4b5 | ||
|
|
0be4d3b11f | ||
|
|
054689b2bf | ||
|
|
95fef21468 | ||
|
|
78ea3b3e3e | ||
|
|
096d8ace8e | ||
|
|
3c13124e9b | ||
|
|
5fa46c0b60 | ||
|
|
ccc9e7cfc6 | ||
|
|
681ba36414 | ||
|
|
e03af51203 | ||
|
|
a555207b20 | ||
|
|
9a4702417a | ||
|
|
e7869b7168 | ||
|
|
166c3250a3 | ||
|
|
2967bf355e | ||
|
|
2ad40b89b3 | ||
|
|
87c2db8296 | ||
|
|
06c297bd1c | ||
|
|
6fe07a207b | ||
|
|
010d4a8a93 | ||
|
|
5f8ea94c1f | ||
|
|
b90dbc3da9 | ||
|
|
a6aed6e4b3 | ||
|
|
a387b19619 | ||
|
|
0c68db43ea | ||
|
|
75b3224a42 | ||
|
|
edbbce8e61 | ||
|
|
f2b34c3ad8 | ||
|
|
581636d767 | ||
|
|
4c4f04ac11 | ||
|
|
ebc2d34cd9 | ||
|
|
6de0e97d97 | ||
|
|
a3f7ddc347 | ||
|
|
15aaa601bd | ||
|
|
8575709f97 | ||
|
|
fde48c980a | ||
|
|
8cacca73bf | ||
|
|
c804e0df05 | ||
|
|
b8a28fbb3a | ||
|
|
4ff6d13771 | ||
|
|
849e990779 | ||
|
|
0baa08336a | ||
|
|
08bd57ef0d | ||
|
|
3c127f2e36 | ||
|
|
9bf5a1ab46 | ||
|
|
e046f5efef | ||
|
|
bc4341fd94 | ||
|
|
68e19472c1 | ||
|
|
5041ff4921 | ||
|
|
6770c7361e | ||
|
|
6bbadfb303 | ||
|
|
cd489264e1 | ||
|
|
bfa59b4a5f | ||
|
|
e5fb2d4e93 | ||
|
|
1178f71d99 | ||
|
|
5d28183fcf | ||
|
|
5b25323c25 | ||
|
|
4ab19eac62 | ||
|
|
9c4b041a80 | ||
|
|
72ef6d7704 | ||
|
|
985dd03ff7 | ||
|
|
0b9b3d8643 | ||
|
|
6c56def33e | ||
|
|
e3a2aeb05d | ||
|
|
1bf039ccd5 | ||
|
|
bb5059ff9b | ||
|
|
7c393d097f | ||
|
|
88faa2b348 | ||
|
|
c6f9b7f4ee | ||
|
|
51957b4162 | ||
|
|
fc3ce72674 | ||
|
|
aab64cdddc | ||
|
|
07d35de056 | ||
|
|
a85e84599b | ||
|
|
e6f8c17ac5 | ||
|
|
fc28be3b23 | ||
|
|
fabc0ed7ad | ||
|
|
9303d428a2 | ||
|
|
c7a92f2cad | ||
|
|
abf05c3e60 | ||
|
|
87aec58f11 | ||
|
|
aacdf98c9a | ||
|
|
4a18771330 | ||
|
|
471362f61f | ||
|
|
2791d9db1e | ||
|
|
007aa7dd65 | ||
|
|
f9e38a7bb9 | ||
|
|
b04ea832a4 | ||
|
|
e5e37e310b | ||
|
|
3d8cde6618 | ||
|
|
fce34bc8ac | ||
|
|
2756b2f004 | ||
|
|
532304e468 | ||
|
|
6bbb8b79eb | ||
|
|
26f6b216a1 | ||
|
|
f8876a22c1 | ||
|
|
e6c8e35dec | ||
|
|
49222c3718 | ||
|
|
0eefe6edb4 | ||
|
|
a35597fc7f | ||
|
|
d5ddb56721 | ||
|
|
ac626ee7ac | ||
|
|
cbb7c65794 | ||
|
|
29f36f7e37 | ||
|
|
9576374952 | ||
|
|
0dc56b6a15 | ||
|
|
92922be83c | ||
|
|
7458f11766 | ||
|
|
487bdac2f9 | ||
|
|
3426f11459 | ||
|
|
f3dfa0c36a | ||
|
|
ab9940293e | ||
|
|
3667d62e06 | ||
|
|
dd2064a0ac | ||
|
|
813201e174 | ||
|
|
cc16c5d805 | ||
|
|
8404253f81 | ||
|
|
09a77e1052 | ||
|
|
19f3eaa657 | ||
|
|
15f0bf47e7 | ||
|
|
9f2167aede | ||
|
|
fbe6fb2773 | ||
|
|
cf0cdfc55e | ||
|
|
2003cd8011 | ||
|
|
08184e32de | ||
|
|
bf89ee7109 | ||
|
|
0353e8d6b8 | ||
|
|
45c9add28c | ||
|
|
d100948ca2 | ||
|
|
bbe1b2217b | ||
|
|
db78fa9abb | ||
|
|
2f52813ebd | ||
|
|
dde6e2b1d3 | ||
|
|
81ad95363a | ||
|
|
8aca4c3495 | ||
|
|
76ff9b3097 | ||
|
|
95d99ae1f0 | ||
|
|
8505967430 | ||
|
|
5a019e148e | ||
|
|
c9e7675c1a | ||
|
|
b605de074d | ||
|
|
f26a48bd52 | ||
|
|
cb2c037c06 | ||
|
|
883e3b840f | ||
|
|
78842b2870 | ||
|
|
02596589e7 | ||
|
|
c797e709a2 | ||
|
|
7272750702 | ||
|
|
09d7d76b21 | ||
|
|
467bb16215 | ||
|
|
5d14586392 | ||
|
|
d26815569f | ||
|
|
c2195c5b7e | ||
|
|
997b491272 | ||
|
|
27d3905cae | ||
|
|
9981cb8b0f | ||
|
|
e067755930 | ||
|
|
135d663159 | ||
|
|
52141c9111 | ||
|
|
7f929d292d | ||
|
|
db328a6b18 | ||
|
|
78bd14b38d | ||
|
|
02b8212be8 | ||
|
|
7de2ba3eae | ||
|
|
5223a4b405 | ||
|
|
474ea305ea | ||
|
|
f1a50db2d1 | ||
|
|
229690a95c | ||
|
|
a5bcf03030 | ||
|
|
899a989d3a | ||
|
|
dc5431ad4b | ||
|
|
1273c39c03 | ||
|
|
b37c279ab5 | ||
|
|
86b7d39a83 | ||
|
|
d0de89a12a | ||
|
|
887f020691 | ||
|
|
0c73623d2c | ||
|
|
8293759056 | ||
|
|
dc5ae1e34c | ||
|
|
5805a14ca6 | ||
|
|
7172e97abe | ||
|
|
169431b84a | ||
|
|
019b750867 | ||
|
|
90ea281f29 | ||
|
|
4c83fdd3d7 | ||
|
|
019dbb4cdc | ||
|
|
cf7968dcea | ||
|
|
c187429865 | ||
|
|
6ab5dbee4f | ||
|
|
37bf29b916 | ||
|
|
907b5124fd | ||
|
|
5201280f70 | ||
|
|
7f6518a4b7 | ||
|
|
984cc04a22 | ||
|
|
a0d122079d | ||
|
|
567ee69b24 | ||
|
|
8192010e32 | ||
|
|
43115f6878 | ||
|
|
f9fc898d56 | ||
|
|
ffa9173378 | ||
|
|
6abddf37f8 | ||
|
|
94e84bbc07 | ||
|
|
fba6f748e8 | ||
|
|
2710f76692 | ||
|
|
1aa674b588 | ||
|
|
50c5921517 | ||
|
|
d10161eafc | ||
|
|
918ad13b56 | ||
|
|
00b6ad1ebf | ||
|
|
00f1580a14 | ||
|
|
e20a29d3b0 | ||
|
|
343fe016ae | ||
|
|
52c71f749d | ||
|
|
b2aabeffc4 | ||
|
|
3b84c803d8 | ||
|
|
1b735da7d5 | ||
|
|
46f048e397 | ||
|
|
095c88e470 | ||
|
|
c457fc3553 | ||
|
|
08bf788ebd | ||
|
|
e9c44a76a2 | ||
|
|
d3df694fa8 | ||
|
|
1f493d1ff8 | ||
|
|
e7fb03c8ae | ||
|
|
1faf288798 | ||
|
|
69f6fd2134 | ||
|
|
703585b244 | ||
|
|
48f5125749 | ||
|
|
8c3b3d3686 | ||
|
|
8f9c9b28a8 | ||
|
|
70566f0563 | ||
|
|
7fa61d7d51 | ||
|
|
a116ab7092 | ||
|
|
1e46c740c3 | ||
|
|
3cf3ce949f | ||
|
|
58168f5bf4 | ||
|
|
44b91a0e76 | ||
|
|
7faae780a5 | ||
|
|
7dd90c9d22 | ||
|
|
32992fa0b1 | ||
|
|
9e95919414 | ||
|
|
d60523bc28 | ||
|
|
2a588555bb | ||
|
|
ed3034e066 | ||
|
|
a4ea8fd8b8 | ||
|
|
05bd964adc | ||
|
|
902ee5060c | ||
|
|
a9a8c5993b | ||
|
|
04f26783c4 | ||
|
|
d2ca083c9f | ||
|
|
4588676cfb | ||
|
|
a8ba2eb3d3 | ||
|
|
81f8b3f31c | ||
|
|
1d1286bfb4 | ||
|
|
11ce75968f | ||
|
|
25ca322957 | ||
|
|
03be30ba3e | ||
|
|
8b118faa61 | ||
|
|
e14f61b924 | ||
|
|
b77dfccf00 | ||
|
|
a21afd421b | ||
|
|
5e831c548f | ||
|
|
667db87a1b | ||
|
|
95340fccb3 | ||
|
|
9d924a0c4a | ||
|
|
b0bdc3c1a8 | ||
|
|
bcf4e0aba8 | ||
|
|
de2a20b411 | ||
|
|
587b8a11d0 | ||
|
|
d279cadbe0 | ||
|
|
560a15e62d | ||
|
|
f59bf76eef | ||
|
|
cedf90a9d6 | ||
|
|
68cd946994 | ||
|
|
025fa11c75 | ||
|
|
0d6980d7a1 | ||
|
|
b48eb90023 | ||
|
|
0b7f864213 | ||
|
|
d9410d2d43 | ||
|
|
ba61de387b | ||
|
|
b47cc0fceb | ||
|
|
31da10b41f | ||
|
|
ac232300a2 | ||
|
|
7e26f01342 | ||
|
|
33dafdb58b | ||
|
|
6279d1293d | ||
|
|
9a858e868c | ||
|
|
5414abb4a0 | ||
|
|
f304d5c8e7 | ||
|
|
d3180b8b97 | ||
|
|
13155e7725 | ||
|
|
24a04f9048 | ||
|
|
99d9a8fe30 | ||
|
|
2250c6b07b | ||
|
|
f67196b2ed | ||
|
|
3713949b6d | ||
|
|
efda2831e5 | ||
|
|
6c4306c27d | ||
|
|
b85d0adadf | ||
|
|
33c57e6223 | ||
|
|
fc61d92bf8 | ||
|
|
27d8a948c1 | ||
|
|
b87078d51e | ||
|
|
d9870c32a9 | ||
|
|
8ee640f979 | ||
|
|
1354c6942c | ||
|
|
353930d212 | ||
|
|
5590c48937 | ||
|
|
cfa03374f8 | ||
|
|
1e160ce559 | ||
|
|
cbf51c5ba0 | ||
|
|
f19700fe52 | ||
|
|
5a69ee0e11 | ||
|
|
9ebca46933 | ||
|
|
73bc3119be | ||
|
|
ab29978e9f | ||
|
|
17c4f1c7f5 | ||
|
|
7534a15c3a | ||
|
|
888e90e823 | ||
|
|
380c4ee32d | ||
|
|
6bae20ca43 | ||
|
|
7a6cb59dbb | ||
|
|
afaefc89eb | ||
|
|
118167a47d | ||
|
|
60b52a1334 | ||
|
|
1d9cf262f7 | ||
|
|
aee0091161 | ||
|
|
faf3c2cd38 | ||
|
|
fa933553da | ||
|
|
f523d7b540 | ||
|
|
38e6dd71bb | ||
|
|
e89ca180c2 | ||
|
|
6fd7f7dd3e | ||
|
|
5d237f0986 | ||
|
|
e717ece4ab | ||
|
|
e5f47d4334 | ||
|
|
88eaf5d6ce | ||
|
|
bad6e169bf | ||
|
|
469d002f4e | ||
|
|
bfe4c0ae07 | ||
|
|
008f27e70a | ||
|
|
cb507ff29a | ||
|
|
cf5083d4cd | ||
|
|
28cdee448d | ||
|
|
89f5b6a0b6 | ||
|
|
416da08102 | ||
|
|
2935b4db0e | ||
|
|
62b6331753 | ||
|
|
4a741a5d5c | ||
|
|
a63147ae77 | ||
|
|
fb65f9b54b | ||
|
|
a661bc87c4 | ||
|
|
fa5022978d | ||
|
|
8c9f6c5531 | ||
|
|
e5de2ad632 | ||
|
|
93921097a6 | ||
|
|
17611f2f73 | ||
|
|
7fd0e1b991 | ||
|
|
0924bcd824 | ||
|
|
ba794ea356 | ||
|
|
83713e7059 | ||
|
|
f1c283f4de | ||
|
|
7488ae014b | ||
|
|
a9fc1cc257 | ||
|
|
a33e3d12cb | ||
|
|
d84a2e7dc0 | ||
|
|
e816401a81 | ||
|
|
7d5ccccd47 | ||
|
|
5fec33012e | ||
|
|
0f513752a0 | ||
|
|
936ed0804d | ||
|
|
300083da27 | ||
|
|
fa63b5514a | ||
|
|
009bd1153e | ||
|
|
346d2449f0 | ||
|
|
011f020447 | ||
|
|
9161464f6c | ||
|
|
b0612009bd | ||
|
|
6f28581b26 | ||
|
|
8c125eaf28 | ||
|
|
27d44a1843 | ||
|
|
18ecb16c30 | ||
|
|
f1ddf6eb04 | ||
|
|
297c752106 | ||
|
|
1d307368a9 | ||
|
|
9f55543c06 | ||
|
|
436f78fab7 | ||
|
|
049dbe7786 | ||
|
|
a81a75184c | ||
|
|
8eba4ac46e | ||
|
|
4677e1a718 | ||
|
|
d567e14e81 | ||
|
|
c4e7fde68a | ||
|
|
ceabb00704 | ||
|
|
250c6af087 | ||
|
|
fb8ea1736b | ||
|
|
14dd5538e9 | ||
|
|
af87a7b0ca | ||
|
|
fdaad9f673 | ||
|
|
909bbe734a | ||
|
|
6a75253311 | ||
|
|
716f1bd46c | ||
|
|
a3a69b400c | ||
|
|
09ed43ed56 | ||
|
|
5b573d650a | ||
|
|
cacd634791 | ||
|
|
ddee66f2e4 | ||
|
|
7ac38a7143 | ||
|
|
d6c881358b | ||
|
|
e7ebe26dd5 | ||
|
|
1e587ae616 | ||
|
|
aad8c94fb7 | ||
|
|
8e5e338727 | ||
|
|
18112f6724 | ||
|
|
5538c2cb00 | ||
|
|
55598d1b3d | ||
|
|
f8629918a8 | ||
|
|
c1b739014f | ||
|
|
c590c590e6 | ||
|
|
372e12b959 | ||
|
|
81abbc203e | ||
|
|
0778f05cab | ||
|
|
370f203a40 | ||
|
|
1954fa390f | ||
|
|
b5331459c2 | ||
|
|
dc73c3332e | ||
|
|
005564813d | ||
|
|
4b639fcf43 | ||
|
|
dd4352b5cd | ||
|
|
102cdf94ed | ||
|
|
5cf3408ba1 | ||
|
|
6b9a507f82 | ||
|
|
f28550d348 | ||
|
|
f6acf8ad7c | ||
|
|
3fbe6e5e49 | ||
|
|
447032eb32 | ||
|
|
fcc7edd48f | ||
|
|
bf692e853d | ||
|
|
0f1ee1caeb | ||
|
|
03009b2e9e | ||
|
|
61ac55314d | ||
|
|
a53337740d | ||
|
|
fc9deb6b0c | ||
|
|
a2676565d3 | ||
|
|
73d28a4068 | ||
|
|
9e41323f13 | ||
|
|
559e8d8e50 | ||
|
|
d29062c4da | ||
|
|
9ab9438fbb | ||
|
|
e9d2e36264 | ||
|
|
e0dcab9d0c | ||
|
|
cd8cfb8675 | ||
|
|
6f3e71606f | ||
|
|
a2db5815c0 | ||
|
|
0a91b2da26 | ||
|
|
6e14846c9f | ||
|
|
d119a5f5c8 | ||
|
|
8c9da4e943 | ||
|
|
afad52c670 | ||
|
|
6b8acc2868 | ||
|
|
484ba02435 | ||
|
|
f546383b73 | ||
|
|
b9d0d3f4c7 | ||
|
|
4d22cc1578 | ||
|
|
412ad22f46 | ||
|
|
1215793007 | ||
|
|
1d2d1e752e | ||
|
|
edf6a708c1 | ||
|
|
9de916eb20 | ||
|
|
df56fcdf52 | ||
|
|
98c59c98ba | ||
|
|
569101bed8 | ||
|
|
1a6ec3c756 | ||
|
|
a912c6ec31 | ||
|
|
bd33326372 | ||
|
|
a5c4dcb553 | ||
|
|
7c5fd6aadc | ||
|
|
ad841b7dac | ||
|
|
fcf54fb7df | ||
|
|
33993798e1 | ||
|
|
71d4e444c1 | ||
|
|
eb366a0312 | ||
|
|
d5a5bc6522 | ||
|
|
824a8b228d | ||
|
|
3be8c5fc64 | ||
|
|
a0e1c23277 | ||
|
|
855b6d7a56 | ||
|
|
f2512710d5 | ||
|
|
130cccba8d | ||
|
|
8b084b683c | ||
|
|
2041979a09 | ||
|
|
9dfe45a84d | ||
|
|
867f664e17 | ||
|
|
adaa685215 | ||
|
|
9e974b86de | ||
|
|
4862363e6a | ||
|
|
47fd87e77f | ||
|
|
8dcb06fd20 | ||
|
|
cf51217148 | ||
|
|
1502d9e44a | ||
|
|
688f9ed6c3 | ||
|
|
a905c45c77 | ||
|
|
c9cb346e56 | ||
|
|
8502727a59 | ||
|
|
8b2a708b19 | ||
|
|
f0c7e76717 | ||
|
|
928d72f365 | ||
|
|
357c5387d7 | ||
|
|
0d7dc0cae1 | ||
|
|
3da61efe3b | ||
|
|
c959151fa2 | ||
|
|
e536a1cc07 | ||
|
|
4f5045299e | ||
|
|
6c056de8a9 | ||
|
|
e88ce7442a | ||
|
|
9f35cafaa1 | ||
|
|
cba70d29ba | ||
|
|
1982d67774 | ||
|
|
67a2ff7f90 | ||
|
|
c19ab86202 | ||
|
|
40b524c58e | ||
|
|
39775e1099 | ||
|
|
113f8d8746 | ||
|
|
3407785536 | ||
|
|
47af3efc6e | ||
|
|
bb6984a833 | ||
|
|
681150f6d3 | ||
|
|
cf26c03ce9 | ||
|
|
d53f9a398a | ||
|
|
326975ada3 | ||
|
|
9be7075f61 | ||
|
|
2a39296d57 | ||
|
|
c1d473849e | ||
|
|
e729d28c08 | ||
|
|
299c5fc202 | ||
|
|
88fe7871be | ||
|
|
cf3ee22597 | ||
|
|
e4bf50b9b9 | ||
|
|
7ff7943455 | ||
|
|
bf93b38561 | ||
|
|
b93a1e6b44 | ||
|
|
4aafcd220d | ||
|
|
13c3757067 | ||
|
|
338c9e704a | ||
|
|
2e520f2768 | ||
|
|
25de2e15a9 | ||
|
|
f03e238f6b | ||
|
|
38dfee802f | ||
|
|
fc838a04be | ||
|
|
bd76fc0492 | ||
|
|
97673cb128 | ||
|
|
6e39af3697 | ||
|
|
22a68fb047 | ||
|
|
a671241a6e | ||
|
|
bc982cc994 | ||
|
|
264d5c446e | ||
|
|
d29ec48504 | ||
|
|
4e177393f0 | ||
|
|
88bb103f75 | ||
|
|
3ac12aecc5 | ||
|
|
e5b8a01fd5 | ||
|
|
02e941d371 | ||
|
|
2f2448aec9 | ||
|
|
34177e673d | ||
|
|
3f7a709676 | ||
|
|
8678ab4c55 | ||
|
|
8851acc5ed | ||
|
|
1e93a3e64e | ||
|
|
ad50c226e6 | ||
|
|
022da62579 | ||
|
|
333ff883e1 | ||
|
|
23c4116ebb | ||
|
|
d4fe243cdf | ||
|
|
a4593f17ca | ||
|
|
b4cbe54ed6 | ||
|
|
221c09aa99 | ||
|
|
0aa6435c45 | ||
|
|
8ce563bf92 | ||
|
|
004c7fa668 | ||
|
|
6daf1a460e | ||
|
|
cdf989adb7 | ||
|
|
1f57aa38cd | ||
|
|
77d451ecca | ||
|
|
0dccc85c98 | ||
|
|
3f6ec144e5 | ||
|
|
cf7f00691f | ||
|
|
8f2fa04181 | ||
|
|
53968c3917 | ||
|
|
67058089b4 | ||
|
|
7d598d658c | ||
|
|
fcea1485bb | ||
|
|
3829cd2f2f | ||
|
|
1a0352d18e | ||
|
|
1e02f2e8a4 | ||
|
|
ee8c72d95a | ||
|
|
aea0cc5041 | ||
|
|
218dfbd547 | ||
|
|
7dffb43267 | ||
|
|
feb2184c4e | ||
|
|
ad59b08f76 | ||
|
|
e43c21112d | ||
|
|
6ca364606b | ||
|
|
ab759be8d9 | ||
|
|
7aa95be980 | ||
|
|
efc6aa0c97 | ||
|
|
8d64b53dc8 | ||
|
|
e7b89d8835 | ||
|
|
ec2ffda599 | ||
|
|
3cf1a082e0 | ||
|
|
c0fd271932 | ||
|
|
ed04e82a04 | ||
|
|
2aa6117bda | ||
|
|
c5449d3eb7 | ||
|
|
caf066f845 | ||
|
|
dd04329367 | ||
|
|
d72560e10d | ||
|
|
cf3ef18fc4 | ||
|
|
a431a93cb1 | ||
|
|
6de4a77df3 | ||
|
|
c8312daad1 | ||
|
|
16a99e967c | ||
|
|
321794c4d5 | ||
|
|
71fa2b2218 | ||
|
|
e7f64756a1 | ||
|
|
8de8499cc9 | ||
|
|
1b0092a76e | ||
|
|
f53ecc21b0 | ||
|
|
f095ea7dd6 | ||
|
|
4d503d1043 | ||
|
|
9638ee1f4e | ||
|
|
77d197e635 | ||
|
|
0a715add2e | ||
|
|
dfa532cc2a | ||
|
|
02d23fbbf4 | ||
|
|
019683e963 | ||
|
|
79bef030f2 | ||
|
|
03a468f9ac | ||
|
|
031fd260f1 | ||
|
|
6af8f63d96 | ||
|
|
525995a3d9 | ||
|
|
cd39224cff | ||
|
|
436a6cc4e7 | ||
|
|
885a81f468 | ||
|
|
716f0ea3cf | ||
|
|
91c985fc28 | ||
|
|
85a3f5b740 | ||
|
|
9a1a8f1d8e | ||
|
|
f33a0a8215 | ||
|
|
5d2b0f93b9 | ||
|
|
c3688e398c | ||
|
|
e07dbaa2f5 | ||
|
|
1d043d56da | ||
|
|
200e50568b | ||
|
|
6a7ddd84bb | ||
|
|
b72aa72a90 | ||
|
|
70bd058352 | ||
|
|
c50aaf3049 | ||
|
|
c6cf7a6111 | ||
|
|
c1729d12b8 | ||
|
|
af56299119 | ||
|
|
9e8cad3be7 | ||
|
|
493a585273 | ||
|
|
6db95602e4 | ||
|
|
ec1365a0c9 | ||
|
|
0f80b1f754 | ||
|
|
0792748646 | ||
|
|
027d12b7d6 | ||
|
|
e7224b7866 | ||
|
|
61af8981b0 | ||
|
|
648538959d | ||
|
|
c4da5d500e | ||
|
|
33ccd0f85e | ||
|
|
fd367c243e | ||
|
|
4c792f2814 | ||
|
|
9930a00ed7 | ||
|
|
38b26b0dc3 | ||
|
|
5e558121fe | ||
|
|
7fcf94eb23 | ||
|
|
19e3c6415c | ||
|
|
c249689b48 | ||
|
|
f94d699c09 | ||
|
|
b76118b736 | ||
|
|
e5f4e8eab9 | ||
|
|
f2be4f6058 | ||
|
|
c485b10416 | ||
|
|
bb0e692151 | ||
|
|
d1327aec1b | ||
|
|
454989ff32 | ||
|
|
6161f35037 | ||
|
|
24f9e42f69 | ||
|
|
6e16582dfd | ||
|
|
29a06a1733 | ||
|
|
4300e50cce | ||
|
|
0f05873c89 | ||
|
|
de3d15bb2c | ||
|
|
01862037c8 | ||
|
|
0fc82ea1cf | ||
|
|
c3e07b22c4 | ||
|
|
e6b089be43 | ||
|
|
8917146a12 | ||
|
|
ff8c490b9a | ||
|
|
250935cab3 | ||
|
|
f1060f5bc4 | ||
|
|
39b3c025fa | ||
|
|
f0290cd127 | ||
|
|
e0dbfdeedc | ||
|
|
75ae90f7a9 | ||
|
|
d649065ea3 | ||
|
|
c961bcc594 | ||
|
|
0f68d80420 | ||
|
|
fb9186d68d | ||
|
|
2fba8189de | ||
|
|
9f879b3c5f | ||
|
|
2c2b9bd455 | ||
|
|
1b755039c6 | ||
|
|
0a9eedfbef | ||
|
|
f7457f5e89 | ||
|
|
a416d5bd2d | ||
|
|
2a6389bb8b | ||
|
|
2be211e971 | ||
|
|
6d3fc82b7f | ||
|
|
48aa76ac35 | ||
|
|
aae7e0f6a4 | ||
|
|
10232eda8e | ||
|
|
511da8cbe5 | ||
|
|
615482af92 | ||
|
|
cce6688c31 | ||
|
|
9d288bf698 | ||
|
|
c7c40d2329 | ||
|
|
25520d8dc3 | ||
|
|
c75f64780b | ||
|
|
f2b311f580 | ||
|
|
11d2bb5429 | ||
|
|
64413a6ca7 | ||
|
|
cbb8be769d | ||
|
|
8d3a4aa891 | ||
|
|
91707ac79e | ||
|
|
552d5cd715 | ||
|
|
e467627f33 | ||
|
|
cd1d01b96a | ||
|
|
b6238b413e | ||
|
|
aa6f5724ec | ||
|
|
21ce8b9671 | ||
|
|
37241e6f95 | ||
|
|
068e799459 | ||
|
|
4ab00912c4 | ||
|
|
78ee83125b | ||
|
|
c810740c36 | ||
|
|
7279a4748f | ||
|
|
b534987110 | ||
|
|
d133524e7c | ||
|
|
59d45d603b | ||
|
|
0586460938 | ||
|
|
4144a11552 | ||
|
|
7b22c1d433 | ||
|
|
89a8174fec | ||
|
|
14f2d03b4b | ||
|
|
33833aefdd | ||
|
|
46b234478f | ||
|
|
72e29c3a73 | ||
|
|
9aaa3c933c | ||
|
|
9ab6e589b0 | ||
|
|
f24b91c9e1 | ||
|
|
80bc1d1d90 | ||
|
|
8a128c2a72 | ||
|
|
9859dde47b | ||
|
|
0aef392f1b | ||
|
|
297c91a857 | ||
|
|
770bf71503 | ||
|
|
c5d118f103 | ||
|
|
e63792e5cf | ||
|
|
d5c6b83431 | ||
|
|
916bdfd9ac | ||
|
|
30097af4ea | ||
|
|
65bea98d74 | ||
|
|
efd566ff93 | ||
|
|
f9d77d66e6 | ||
|
|
bdcc14051b | ||
|
|
c85a68123f | ||
|
|
07a1fd413f | ||
|
|
4970388c23 | ||
|
|
9cb3664c0e | ||
|
|
fa76102929 | ||
|
|
4823dc364e | ||
|
|
490ba1ad25 | ||
|
|
b4334460cb | ||
|
|
ea94451f20 | ||
|
|
091f0804e4 | ||
|
|
659c2c98e1 | ||
|
|
1fcb5fc755 | ||
|
|
d9a0cbb1b7 | ||
|
|
2b93fde9da | ||
|
|
deb33056d1 | ||
|
|
daf2fb42e6 | ||
|
|
a06e39a945 | ||
|
|
b5454b245a | ||
|
|
13501fe45f | ||
|
|
977dccd12c | ||
|
|
7a3bae768e | ||
|
|
a61e506200 | ||
|
|
6b9cb8c489 | ||
|
|
2613b5e9d6 | ||
|
|
5cce322a09 | ||
|
|
b00c09026c | ||
|
|
9d380d8872 | ||
|
|
063e965d7d | ||
|
|
b5083af67a | ||
|
|
4df51c8de4 | ||
|
|
bfdcccd8a1 | ||
|
|
2e3f77316d | ||
|
|
7c1f6d1862 | ||
|
|
e6a136e864 | ||
|
|
cbfc15b11b | ||
|
|
c28dbdf665 | ||
|
|
d324c6b025 | ||
|
|
109ef96a5f | ||
|
|
1b17559327 | ||
|
|
c96c3fa2b3 | ||
|
|
abd447e339 | ||
|
|
40ef86f27d | ||
|
|
66df6e7c7f | ||
|
|
5c9d315572 | ||
|
|
4914ae4622 | ||
|
|
6074403d2d | ||
|
|
3c065ac46a | ||
|
|
05029a47a1 | ||
|
|
0ac48f8f65 | ||
|
|
0adb805db9 | ||
|
|
fab5454a16 | ||
|
|
44ce668063 | ||
|
|
42e5c2ad8a | ||
|
|
93748c3e4f | ||
|
|
30d2d9783e | ||
|
|
f8cfb72a32 | ||
|
|
efe7d4e5a2 | ||
|
|
8bc8f2711a | ||
|
|
cb61bfa695 | ||
|
|
507c55b227 | ||
|
|
99235fd908 | ||
|
|
cb3072ca4a | ||
|
|
6b55b8dc93 | ||
|
|
e8bcce1255 | ||
|
|
79dd1ee907 | ||
|
|
24659dbca3 | ||
|
|
51f951292a | ||
|
|
ed2514a22c | ||
|
|
a129905c70 | ||
|
|
4fcc4f816e | ||
|
|
83b47af18d | ||
|
|
f330444a09 | ||
|
|
c2005c578b | ||
|
|
8735c17ceb | ||
|
|
fced640a0a | ||
|
|
2becffaef5 | ||
|
|
b6fef12481 | ||
|
|
c67dd39adc | ||
|
|
dcbbb81605 | ||
|
|
08d7f44c39 | ||
|
|
cb37db126e | ||
|
|
b00aa8f216 | ||
|
|
a301f5e03d | ||
|
|
9b88762b17 | ||
|
|
5f5552d846 | ||
|
|
429d304bc1 | ||
|
|
66e6fb84de | ||
|
|
b1a3871542 | ||
|
|
b5f8b70ce5 | ||
|
|
a2c87a3dda | ||
|
|
91b8236cdd | ||
|
|
46cd6ee9bd | ||
|
|
e6e2d886d3 | ||
|
|
e38e2ad86e | ||
|
|
c0f708c03a | ||
|
|
f0e0a7e7e9 | ||
|
|
571072b84b | ||
|
|
7ea59de69c | ||
|
|
f7fbc54bd1 | ||
|
|
8102aeb368 | ||
|
|
8fce4b8543 | ||
|
|
68d9a14e9f | ||
|
|
78b0bd0a0d | ||
|
|
09368fcf99 | ||
|
|
ce4b35d510 | ||
|
|
c453ae53d0 | ||
|
|
f34deab243 | ||
|
|
ccc809f30c | ||
|
|
431e35913e | ||
|
|
240ae9729e | ||
|
|
836e83c49f | ||
|
|
02734b6457 | ||
|
|
e0413094fb | ||
|
|
954e560f9e | ||
|
|
50a164a1f6 | ||
|
|
e3d001ea43 | ||
|
|
de661cdbc5 | ||
|
|
86088511bd | ||
|
|
28eb784e46 | ||
|
|
cf9c95c32c | ||
|
|
043b698a87 | ||
|
|
ef8f7c1211 | ||
|
|
6ab062124d | ||
|
|
76d4fdd391 | ||
|
|
c7d77b32dc | ||
|
|
6adfba7c0f | ||
|
|
42c08a3f52 | ||
|
|
79c5a533cd | ||
|
|
a8dc9694a4 | ||
|
|
df3849370a | ||
|
|
1815961469 | ||
|
|
938b8dfc73 | ||
|
|
5e5bef6c18 | ||
|
|
c3c1c6f405 | ||
|
|
10cdeab42a | ||
|
|
267f73a1f7 | ||
|
|
2ca7d42e7e | ||
|
|
351ca31238 | ||
|
|
04cb49385e | ||
|
|
7174d637e8 | ||
|
|
6231b6b077 | ||
|
|
7d2618bc70 | ||
|
|
697bf5beff | ||
|
|
6bbbe31656 | ||
|
|
13fb7c1b88 | ||
|
|
68d6a5073a | ||
|
|
ebc6e058db | ||
|
|
339ef0ce7a | ||
|
|
1d69ceee5c | ||
|
|
9425616615 | ||
|
|
90fe1cffbf | ||
|
|
84f982080a | ||
|
|
3d89d059dc | ||
|
|
0cfa89c0eb | ||
|
|
935a837c01 | ||
|
|
5c613ea881 | ||
|
|
7667733991 | ||
|
|
342a368fd4 | ||
|
|
db084506d8 | ||
|
|
48589e8d07 | ||
|
|
95428a5926 | ||
|
|
0fc0c1a32d | ||
|
|
dca86af8f4 | ||
|
|
bab2912b5e | ||
|
|
95d35a4a0b | ||
|
|
d1d11fc6dd | ||
|
|
4aeabf1b0d | ||
|
|
7ded038af5 | ||
|
|
3287f5519e | ||
|
|
b347c3c5e5 | ||
|
|
2b7196a8bb | ||
|
|
83ecafbd95 | ||
|
|
a570cefcf8 | ||
|
|
72eda13e50 | ||
|
|
1226e734a0 | ||
|
|
8878fa4f9a | ||
|
|
827e1b3fef | ||
|
|
0353f596e9 | ||
|
|
da2d4a7afc | ||
|
|
389efb289e | ||
|
|
aa703adb46 | ||
|
|
ad574d4008 | ||
|
|
8537826eb4 | ||
|
|
aa6c754635 | ||
|
|
3ef0db078e | ||
|
|
557cb9a879 | ||
|
|
c1e51beba6 | ||
|
|
44dba01f3e | ||
|
|
47bc2a5741 | ||
|
|
02e734168c | ||
|
|
a614262edb | ||
|
|
875aa1c58c | ||
|
|
05f33142f5 | ||
|
|
3c4b56c4dd | ||
|
|
272dbaa13f | ||
|
|
5340d1424d | ||
|
|
ec6b8d8b76 | ||
|
|
e4af6a42a7 | ||
|
|
eeaf8e6b6c | ||
|
|
38cfc45e07 | ||
|
|
a90f8b8c8f | ||
|
|
d1c5cd4a30 | ||
|
|
be5d1693fb | ||
|
|
e9336e4dfc | ||
|
|
94493e606d | ||
|
|
af3a8381ef | ||
|
|
9bce2f76fb | ||
|
|
195bf52bca | ||
|
|
9fce131de8 | ||
|
|
404c512786 | ||
|
|
a10814e11e | ||
|
|
1f984a5a63 | ||
|
|
682dad0ec7 | ||
|
|
6e695da2d9 | ||
|
|
fec5988657 | ||
|
|
f6a7b17a35 | ||
|
|
1e403064b9 | ||
|
|
03c01bc3c0 | ||
|
|
961668c91c | ||
|
|
df59bb8986 | ||
|
|
876c8b03e6 | ||
|
|
5456aee6fc | ||
|
|
5712456bd9 | ||
|
|
0c0f3efdeb | ||
|
|
286480de9b | ||
|
|
9a019bce84 | ||
|
|
c4b69eb0eb | ||
|
|
c6eba0b47a | ||
|
|
acc4addb60 | ||
|
|
7823fbb45c | ||
|
|
9fb593d0fc | ||
|
|
7538501ad1 | ||
|
|
dd1391a005 | ||
|
|
35d9eadf08 | ||
|
|
7485498773 | ||
|
|
95247be0bf | ||
|
|
6ed7f7a516 | ||
|
|
907f88c4e6 | ||
|
|
f9c25498eb | ||
|
|
907544a328 | ||
|
|
c582aacb7a | ||
|
|
1badceada8 | ||
|
|
0107373234 | ||
|
|
8cc04ef505 | ||
|
|
6f49446dfa | ||
|
|
abd00505d1 | ||
|
|
d1cad9c3f5 | ||
|
|
a45d5d3f94 | ||
|
|
599003969d | ||
|
|
18eaf8e6fc | ||
|
|
937c97faed | ||
|
|
8b0a5b8718 | ||
|
|
18b6e9a36f | ||
|
|
13efa8a089 | ||
|
|
1a69cb286f | ||
|
|
89a1ab395c | ||
|
|
a39e83d743 | ||
|
|
c1924b9ff0 | ||
|
|
368e3d9293 | ||
|
|
bb8ca08816 | ||
|
|
57c83b330e | ||
|
|
f70134f729 | ||
|
|
5c772f38fa | ||
|
|
b3ad81288f | ||
|
|
432e875dce | ||
|
|
00380700fb | ||
|
|
6779be2487 | ||
|
|
c0874f2441 | ||
|
|
e25ccffcef | ||
|
|
5a7c8d8c1d | ||
|
|
c0035cc480 | ||
|
|
329e340dc5 | ||
|
|
6eaca90d65 | ||
|
|
ed5a6bd947 | ||
|
|
988f27bfcf | ||
|
|
3c8bd0d3de | ||
|
|
4c6c82a2e8 | ||
|
|
ba1bed68ec | ||
|
|
32a6a55b66 | ||
|
|
260da6ca8d | ||
|
|
fd5463571e | ||
|
|
875da8c666 | ||
|
|
6d5d4395b5 | ||
|
|
f98565755a | ||
|
|
7a8c7853c1 | ||
|
|
14a7aada68 | ||
|
|
34aa5e1d21 | ||
|
|
4ac6727438 | ||
|
|
e2c1ea9422 | ||
|
|
27bd9939a3 | ||
|
|
bb5f9e431f | ||
|
|
4958987b2a | ||
|
|
d46c1f2349 | ||
|
|
afd73539bb | ||
|
|
1c8fa6a5ca | ||
|
|
f8cd25df1d | ||
|
|
ff70d988c6 | ||
|
|
78bca69138 | ||
|
|
e76714f4eb | ||
|
|
090eaadf20 | ||
|
|
28e0393f23 | ||
|
|
204e77e059 | ||
|
|
efe1b1dbf7 | ||
|
|
355e586f45 | ||
|
|
eb71ef9235 | ||
|
|
c89bcae560 | ||
|
|
3c28b4a8ff | ||
|
|
d2ef991f9e | ||
|
|
ac898d221f | ||
|
|
b9d3fbe0c5 | ||
|
|
d5349112e8 | ||
|
|
4d90ae4b49 | ||
|
|
e5bd08185a | ||
|
|
105da4128d | ||
|
|
48b2713553 | ||
|
|
9604f69005 | ||
|
|
d1c2949eb4 | ||
|
|
027cc8c873 | ||
|
|
9909b5414e | ||
|
|
5b618b7cae | ||
|
|
aac86aa093 | ||
|
|
3b1c766802 | ||
|
|
4fb8b217e6 | ||
|
|
6cfb488500 | ||
|
|
590265eaf1 | ||
|
|
238cc11cce | ||
|
|
7cdb078673 | ||
|
|
17a3d31d85 | ||
|
|
4fbd678f99 | ||
|
|
67cf8908bc | ||
|
|
331b029590 | ||
|
|
0839d02b4c | ||
|
|
392d577c49 | ||
|
|
10ad97bc55 | ||
|
|
9953279978 | ||
|
|
9568a284ab | ||
|
|
3ba144f81d | ||
|
|
8678ecd1ef | ||
|
|
8dc6f3f5c2 | ||
|
|
f0a4485e54 | ||
|
|
af99a61697 | ||
|
|
11af20dbeb | ||
|
|
646f831fbd | ||
|
|
3eb10fcf21 | ||
|
|
b831fafceb | ||
|
|
eef57c1e99 | ||
|
|
35e55871ab | ||
|
|
5aa655f79a | ||
|
|
f33755ef1f | ||
|
|
753dcbe5f9 | ||
|
|
f512a311f2 | ||
|
|
22cfc841d5 | ||
|
|
56686b4514 | ||
|
|
e7c0e157d2 | ||
|
|
a8122bb957 | ||
|
|
3e63170fdd | ||
|
|
9a8a6a1b35 | ||
|
|
33768c24af | ||
|
|
968bbc7bb2 | ||
|
|
53c9ffd06f | ||
|
|
11d3899c60 | ||
|
|
94322a9f9b | ||
|
|
4e406f702c | ||
|
|
ade60d4fe9 | ||
|
|
0a5c176011 | ||
|
|
91f55290ef | ||
|
|
9fe188e4a5 | ||
|
|
8d69a6e816 | ||
|
|
b1d49f24b4 | ||
|
|
fb29aec42c | ||
|
|
09f3615606 | ||
|
|
0880b42129 | ||
|
|
84ca7a9f0f | ||
|
|
a40d486215 | ||
|
|
c178b2d192 | ||
|
|
2778b1cbb9 | ||
|
|
63b57c311d | ||
|
|
d32c38c75c | ||
|
|
1ac858794a | ||
|
|
6a5a08ee1c | ||
|
|
eee6afe0b9 | ||
|
|
44da65fb44 | ||
|
|
c38fc52df4 | ||
|
|
727ca802bf | ||
|
|
3944cfb14d | ||
|
|
0367f32ea8 | ||
|
|
e9db70fb63 | ||
|
|
177601b561 | ||
|
|
97629f5961 | ||
|
|
33cc1bd21d | ||
|
|
0f840cc3eb | ||
|
|
5311ad9e83 | ||
|
|
dff3ea7ab3 | ||
|
|
e4663e6da1 | ||
|
|
d1893f64e0 | ||
|
|
9ffcb469fb | ||
|
|
253a200d3b | ||
|
|
d738ce2b0a | ||
|
|
387a10e3dc | ||
|
|
c557efafeb | ||
|
|
a167244346 | ||
|
|
54fbf7e55f | ||
|
|
c67fca154e | ||
|
|
b5480b3594 | ||
|
|
55118ad061 | ||
|
|
2f943131df | ||
|
|
3787b17439 | ||
|
|
717be7bcd5 | ||
|
|
1559afda85 | ||
|
|
9581f3d49a | ||
|
|
250213ac7e | ||
|
|
0681f6f1df | ||
|
|
14b0443792 | ||
|
|
7c6144bc4a | ||
|
|
a2832f1b5b | ||
|
|
305fac7a19 | ||
|
|
f73feedb9e | ||
|
|
7330108009 | ||
|
|
a4d0c7148b | ||
|
|
ec36a2b061 | ||
|
|
8b9efaa161 | ||
|
|
dab7515aa4 | ||
|
|
d6695b8a0e | ||
|
|
49d9730f60 | ||
|
|
b37e8b0e00 | ||
|
|
6f1f0d896a | ||
|
|
0919edd4d2 | ||
|
|
30ee689da3 | ||
|
|
f07d73b9bf | ||
|
|
104636a39a | ||
|
|
aa5d53eb17 | ||
|
|
8edbe4d6db | ||
|
|
48365e10bb | ||
|
|
0d65cae638 | ||
|
|
1dc18077b8 | ||
|
|
f757782f22 | ||
|
|
5283e57786 | ||
|
|
9fbc394036 | ||
|
|
cdffec73e9 | ||
|
|
22850493b6 | ||
|
|
c93e5cc3e9 | ||
|
|
bf0ff0907e | ||
|
|
69f4930041 | ||
|
|
f5bed806fb | ||
|
|
88cae8b422 | ||
|
|
2b3f1d36b3 | ||
|
|
e15fb2bb99 | ||
|
|
3e2273fcee | ||
|
|
24e2b4c005 | ||
|
|
d7c8bc77c6 | ||
|
|
d1486c3837 | ||
|
|
a245d9f88c | ||
|
|
40cedd6763 | ||
|
|
96baa73ed9 | ||
|
|
63def292eb | ||
|
|
35921b897b | ||
|
|
49f5903dd2 | ||
|
|
7f4bab0697 | ||
|
|
c7b31a5c49 | ||
|
|
731dcd3e6a | ||
|
|
30e325a94b | ||
|
|
e7569225f1 | ||
|
|
e5c57c580a | ||
|
|
11bac096f2 | ||
|
|
2ec5ed258a | ||
|
|
254d3e172a | ||
|
|
6ef5d8c4ed | ||
|
|
9c62f9282f | ||
|
|
13e0cfb8c7 | ||
|
|
ea78294030 | ||
|
|
56ab215dad | ||
|
|
c335bfeb56 | ||
|
|
c1629ca53b | ||
|
|
3ec1601e37 | ||
|
|
6e9ed38d1f | ||
|
|
c00abfa3ee | ||
|
|
0c8110efe1 | ||
|
|
7dfed5cf21 | ||
|
|
fe8ecc843b | ||
|
|
8c95116d96 | ||
|
|
d894d34d04 | ||
|
|
7eeb7671d5 | ||
|
|
4fd0ba8f6f | ||
|
|
4d3cf45992 | ||
|
|
66f2f65ef7 | ||
|
|
af084fbec1 | ||
|
|
5f9e089b1d | ||
|
|
4ae193eec7 | ||
|
|
0f34e35d26 | ||
|
|
7c5fe4cbff | ||
|
|
e9b18242eb | ||
|
|
83388fb0af | ||
|
|
4aa50c17df | ||
|
|
5bbacd9bda | ||
|
|
b0ab6a3bbd | ||
|
|
49c34da379 | ||
|
|
35ec6d2b88 | ||
|
|
140182b96c | ||
|
|
80b30f46a5 | ||
|
|
7104079efb | ||
|
|
164ba2a2d8 | ||
|
|
db88473ea9 | ||
|
|
09c2809a50 | ||
|
|
2096296421 | ||
|
|
edaf8c4596 | ||
|
|
0e929ef94d | ||
|
|
843e2bad4b | ||
|
|
73e75e9dbc | ||
|
|
0694844fae | ||
|
|
a08bfb778a | ||
|
|
72a6cb62ee | ||
|
|
35b3bd3e3b | ||
|
|
dcbe42298a | ||
|
|
af38f6fca4 | ||
|
|
4bc259db3d | ||
|
|
b49ac0b160 | ||
|
|
bc54f9dc00 | ||
|
|
c7c69d88af | ||
|
|
e26c712ab2 | ||
|
|
707cd03658 | ||
|
|
45222e5b20 | ||
|
|
786f1af891 | ||
|
|
634d0bdc7c | ||
|
|
51c0c35c6a | ||
|
|
f08141c734 | ||
|
|
ff7fe99342 | ||
|
|
85514c40ae | ||
|
|
9b3ad185dc | ||
|
|
fe4160d8e3 | ||
|
|
70e514ce78 | ||
|
|
46d2cc5714 | ||
|
|
444acd771b | ||
|
|
b0df5e0f9e | ||
|
|
35486a6b88 | ||
|
|
0ca0cc240b | ||
|
|
ba69089e65 | ||
|
|
7467833401 | ||
|
|
d3cee565ad | ||
|
|
bd9db2f55b | ||
|
|
7d2b7b6944 | ||
|
|
b934148fb6 | ||
|
|
a9253a2029 | ||
|
|
a7d26f4e80 | ||
|
|
12fac1c281 | ||
|
|
3813c2bc46 | ||
|
|
498866b699 | ||
|
|
de00c163c7 | ||
|
|
493d02347c | ||
|
|
4f5108090a | ||
|
|
4aafd01861 | ||
|
|
be3559ba07 | ||
|
|
4101154d5b | ||
|
|
a3a1b2d052 | ||
|
|
01bb4a318d | ||
|
|
2b39bcec29 | ||
|
|
696ee004a5 | ||
|
|
6d43a53a0c | ||
|
|
2c32861814 | ||
|
|
4b594d3d00 | ||
|
|
506e3b136c | ||
|
|
4b0ef55f10 | ||
|
|
51c357083c | ||
|
|
dfd054649f | ||
|
|
73e06f33b5 | ||
|
|
88b3b23619 | ||
|
|
365fa8d12d | ||
|
|
893468dd04 | ||
|
|
94266f4f34 | ||
|
|
6727943ceb | ||
|
|
47c7fd984e | ||
|
|
27a739b650 | ||
|
|
1ef285bfe9 | ||
|
|
0a6cab1dbc | ||
|
|
67e5b45dad | ||
|
|
3eb719f6b0 | ||
|
|
ba78f80b01 | ||
|
|
b86b76bb4a | ||
|
|
bfeac5e19c | ||
|
|
cca1b39586 | ||
|
|
366bf3c2b6 | ||
|
|
981f09a1f1 | ||
|
|
88b9e90a56 | ||
|
|
2e0aa9fb28 | ||
|
|
3edad6e887 | ||
|
|
bdaa257674 | ||
|
|
fff670456d | ||
|
|
8a4292441f | ||
|
|
71c156070c | ||
|
|
4bfed0b32e | ||
|
|
eb7b5f660d | ||
|
|
f847a16a7c | ||
|
|
0526305151 | ||
|
|
325b96dcac | ||
|
|
b6da40ad82 | ||
|
|
236623cf2c | ||
|
|
f0dee7765a | ||
|
|
c655b5f5f5 | ||
|
|
232098a774 | ||
|
|
01ba752a0d | ||
|
|
c6d31ecce0 | ||
|
|
3ff3313502 | ||
|
|
79fe7246c1 | ||
|
|
f1c4b79d72 | ||
|
|
48c7de0fce | ||
|
|
ed8bddaac8 | ||
|
|
37d17b6518 | ||
|
|
df33be4b22 | ||
|
|
5a27b3bb85 | ||
|
|
18aea429af | ||
|
|
d3e5545fa6 | ||
|
|
4ac2ae3a4d | ||
|
|
20484048a9 | ||
|
|
6a9ed8d2b6 | ||
|
|
8198be113d | ||
|
|
1e48f74d9a | ||
|
|
3a27961cf3 | ||
|
|
2cdc12742d | ||
|
|
a8dad55c82 | ||
|
|
704985e65a | ||
|
|
52bb9dd45c | ||
|
|
cffcfdb809 | ||
|
|
056c741ac7 | ||
|
|
ebc48efe37 | ||
|
|
4b447e7b05 | ||
|
|
00ca5c1c98 | ||
|
|
cd7c7a9d3b | ||
|
|
6a9f0db997 | ||
|
|
8806955dbd | ||
|
|
4f16f11993 | ||
|
|
3fa0129caf | ||
|
|
f53153db42 | ||
|
|
2858110294 | ||
|
|
2afe7320c8 | ||
|
|
0f29a024af | ||
|
|
4b7043f804 | ||
|
|
3e8cceb3fc | ||
|
|
7c514e2dfd | ||
|
|
6c81e37916 | ||
|
|
07154b0216 | ||
|
|
8e273b23ad | ||
|
|
38debe512e | ||
|
|
b2ec0a0d1c | ||
|
|
09ff5f2792 | ||
|
|
c4b4db4b12 | ||
|
|
31341374d7 | ||
|
|
b8bc026c72 | ||
|
|
4ce81d666e | ||
|
|
ab3042ba3b | ||
|
|
9fc691efbe | ||
|
|
b3cc3a07b0 | ||
|
|
26addefc34 | ||
|
|
a396e2017f |
@@ -1,11 +1,10 @@
|
|||||||
---
|
---
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
# BasedOnStyle: Google
|
# BasedOnStyle: Google
|
||||||
# Generated with clang-format 4.0.1
|
# Generated with clang-format 3.7.1
|
||||||
AccessModifierOffset: -1
|
AccessModifierOffset: -1
|
||||||
AlignAfterOpenBracket: Align
|
AlignAfterOpenBracket: true
|
||||||
AlignConsecutiveAssignments: false
|
AlignConsecutiveAssignments: false
|
||||||
AlignConsecutiveDeclarations: false
|
|
||||||
AlignEscapedNewlinesLeft: true
|
AlignEscapedNewlinesLeft: true
|
||||||
AlignOperands: true
|
AlignOperands: true
|
||||||
AlignTrailingComments: true
|
AlignTrailingComments: true
|
||||||
@@ -16,29 +15,14 @@ AllowShortFunctionsOnASingleLine: All
|
|||||||
AllowShortIfStatementsOnASingleLine: true
|
AllowShortIfStatementsOnASingleLine: true
|
||||||
AllowShortLoopsOnASingleLine: true
|
AllowShortLoopsOnASingleLine: true
|
||||||
AlwaysBreakAfterDefinitionReturnType: None
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
AlwaysBreakAfterReturnType: None
|
|
||||||
AlwaysBreakBeforeMultilineStrings: true
|
AlwaysBreakBeforeMultilineStrings: true
|
||||||
AlwaysBreakTemplateDeclarations: true
|
AlwaysBreakTemplateDeclarations: true
|
||||||
BinPackArguments: true
|
BinPackArguments: true
|
||||||
BinPackParameters: true
|
BinPackParameters: true
|
||||||
BraceWrapping:
|
|
||||||
AfterClass: false
|
|
||||||
AfterControlStatement: false
|
|
||||||
AfterEnum: false
|
|
||||||
AfterFunction: false
|
|
||||||
AfterNamespace: false
|
|
||||||
AfterObjCDeclaration: false
|
|
||||||
AfterStruct: false
|
|
||||||
AfterUnion: false
|
|
||||||
BeforeCatch: false
|
|
||||||
BeforeElse: false
|
|
||||||
IndentBraces: false
|
|
||||||
BreakBeforeBinaryOperators: None
|
BreakBeforeBinaryOperators: None
|
||||||
BreakBeforeBraces: Attach
|
BreakBeforeBraces: Attach
|
||||||
BreakBeforeTernaryOperators: true
|
BreakBeforeTernaryOperators: true
|
||||||
BreakConstructorInitializersBeforeComma: false
|
BreakConstructorInitializersBeforeComma: false
|
||||||
BreakAfterJavaFieldAnnotations: false
|
|
||||||
BreakStringLiterals: true
|
|
||||||
ColumnLimit: 80
|
ColumnLimit: 80
|
||||||
CommentPragmas: '^ IWYU pragma:'
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
@@ -49,19 +33,9 @@ DerivePointerAlignment: false
|
|||||||
DisableFormat: false
|
DisableFormat: false
|
||||||
ExperimentalAutoDetectBinPacking: false
|
ExperimentalAutoDetectBinPacking: false
|
||||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||||
IncludeCategories:
|
|
||||||
- Regex: '^<.*\.h>'
|
|
||||||
Priority: 1
|
|
||||||
- Regex: '^<.*'
|
|
||||||
Priority: 2
|
|
||||||
- Regex: '.*'
|
|
||||||
Priority: 3
|
|
||||||
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
|
||||||
IndentCaseLabels: true
|
IndentCaseLabels: true
|
||||||
IndentWidth: 2
|
IndentWidth: 2
|
||||||
IndentWrappedFunctionNames: false
|
IndentWrappedFunctionNames: false
|
||||||
JavaScriptQuotes: Leave
|
|
||||||
JavaScriptWrapImports: true
|
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
MacroBlockBegin: ''
|
MacroBlockBegin: ''
|
||||||
MacroBlockEnd: ''
|
MacroBlockEnd: ''
|
||||||
@@ -77,10 +51,7 @@ PenaltyBreakString: 1000
|
|||||||
PenaltyExcessCharacter: 1000000
|
PenaltyExcessCharacter: 1000000
|
||||||
PenaltyReturnTypeOnItsOwnLine: 200
|
PenaltyReturnTypeOnItsOwnLine: 200
|
||||||
PointerAlignment: Right
|
PointerAlignment: Right
|
||||||
ReflowComments: true
|
|
||||||
SortIncludes: false
|
|
||||||
SpaceAfterCStyleCast: false
|
SpaceAfterCStyleCast: false
|
||||||
SpaceAfterTemplateKeyword: true
|
|
||||||
SpaceBeforeAssignmentOperators: true
|
SpaceBeforeAssignmentOperators: true
|
||||||
SpaceBeforeParens: ControlStatements
|
SpaceBeforeParens: ControlStatements
|
||||||
SpaceInEmptyParentheses: false
|
SpaceInEmptyParentheses: false
|
||||||
|
|||||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -37,9 +37,9 @@
|
|||||||
/examples/twopass_encoder
|
/examples/twopass_encoder
|
||||||
/examples/vp8_multi_resolution_encoder
|
/examples/vp8_multi_resolution_encoder
|
||||||
/examples/vp8cx_set_ref
|
/examples/vp8cx_set_ref
|
||||||
/examples/vp9cx_set_ref
|
|
||||||
/examples/vp9_lossless_encoder
|
/examples/vp9_lossless_encoder
|
||||||
/examples/vp9_spatial_svc_encoder
|
/examples/vp9_spatial_scalable_encoder
|
||||||
|
/examples/vpx_temporal_scalable_patterns
|
||||||
/examples/vpx_temporal_svc_encoder
|
/examples/vpx_temporal_svc_encoder
|
||||||
/ivfdec
|
/ivfdec
|
||||||
/ivfdec.dox
|
/ivfdec.dox
|
||||||
@@ -50,9 +50,6 @@
|
|||||||
/samples.dox
|
/samples.dox
|
||||||
/test_intra_pred_speed
|
/test_intra_pred_speed
|
||||||
/test_libvpx
|
/test_libvpx
|
||||||
/tools.dox
|
|
||||||
/tools/*.dox
|
|
||||||
/tools/tiny_ssim
|
|
||||||
/vp8_api1_migration.dox
|
/vp8_api1_migration.dox
|
||||||
/vp[89x]_rtcd.h
|
/vp[89x]_rtcd.h
|
||||||
/vpx.pc
|
/vpx.pc
|
||||||
|
|||||||
12
.mailmap
12
.mailmap
@@ -3,8 +3,6 @@ Aℓex Converse <aconverse@google.com>
|
|||||||
Aℓex Converse <aconverse@google.com> <alex.converse@gmail.com>
|
Aℓex Converse <aconverse@google.com> <alex.converse@gmail.com>
|
||||||
Alexis Ballier <aballier@gentoo.org> <alexis.ballier@gmail.com>
|
Alexis Ballier <aballier@gentoo.org> <alexis.ballier@gmail.com>
|
||||||
Alpha Lam <hclam@google.com> <hclam@chromium.org>
|
Alpha Lam <hclam@google.com> <hclam@chromium.org>
|
||||||
Chris Cunningham <chcunningham@chromium.org>
|
|
||||||
Daniele Castagna <dcastagna@chromium.org> <dcastagna@google.com>
|
|
||||||
Deb Mukherjee <debargha@google.com>
|
Deb Mukherjee <debargha@google.com>
|
||||||
Erik Niemeyer <erik.a.niemeyer@intel.com> <erik.a.niemeyer@gmail.com>
|
Erik Niemeyer <erik.a.niemeyer@intel.com> <erik.a.niemeyer@gmail.com>
|
||||||
Guillaume Martres <gmartres@google.com> <smarter3@gmail.com>
|
Guillaume Martres <gmartres@google.com> <smarter3@gmail.com>
|
||||||
@@ -15,28 +13,20 @@ Jim Bankoski <jimbankoski@google.com>
|
|||||||
Johann Koenig <johannkoenig@google.com>
|
Johann Koenig <johannkoenig@google.com>
|
||||||
Johann Koenig <johannkoenig@google.com> <johann.koenig@duck.com>
|
Johann Koenig <johannkoenig@google.com> <johann.koenig@duck.com>
|
||||||
Johann Koenig <johannkoenig@google.com> <johann.koenig@gmail.com>
|
Johann Koenig <johannkoenig@google.com> <johann.koenig@gmail.com>
|
||||||
Johann Koenig <johannkoenig@google.com> <johannkoenig@chromium.org>
|
|
||||||
John Koleszar <jkoleszar@google.com>
|
John Koleszar <jkoleszar@google.com>
|
||||||
Joshua Litt <joshualitt@google.com> <joshualitt@chromium.org>
|
Joshua Litt <joshualitt@google.com> <joshualitt@chromium.org>
|
||||||
Marco Paniconi <marpan@google.com>
|
Marco Paniconi <marpan@google.com>
|
||||||
Marco Paniconi <marpan@google.com> <marpan@chromium.org>
|
Marco Paniconi <marpan@google.com> <marpan@chromium.org>
|
||||||
Pascal Massimino <pascal.massimino@gmail.com>
|
Pascal Massimino <pascal.massimino@gmail.com>
|
||||||
Paul Wilkins <paulwilkins@google.com>
|
Paul Wilkins <paulwilkins@google.com>
|
||||||
Peter Boström <pbos@chromium.org> <pbos@google.com>
|
|
||||||
Peter de Rivaz <peter.derivaz@gmail.com>
|
|
||||||
Peter de Rivaz <peter.derivaz@gmail.com> <peter.derivaz@argondesign.com>
|
|
||||||
Ralph Giles <giles@xiph.org> <giles@entropywave.com>
|
Ralph Giles <giles@xiph.org> <giles@entropywave.com>
|
||||||
Ralph Giles <giles@xiph.org> <giles@mozilla.com>
|
Ralph Giles <giles@xiph.org> <giles@mozilla.com>
|
||||||
Ronald S. Bultje <rsbultje@gmail.com> <rbultje@google.com>
|
Ronald S. Bultje <rsbultje@gmail.com> <rbultje@google.com>
|
||||||
Sami Pietilä <samipietila@google.com>
|
Sami Pietilä <samipietila@google.com>
|
||||||
Shiyou Yin <yinshiyou-hf@loongson.cn>
|
|
||||||
Tamar Levy <tamar.levy@intel.com>
|
Tamar Levy <tamar.levy@intel.com>
|
||||||
Tamar Levy <tamar.levy@intel.com> <levytamar82@gmail.com>
|
Tamar Levy <tamar.levy@intel.com> <levytamar82@gmail.com>
|
||||||
Tero Rintaluoma <teror@google.com> <tero.rintaluoma@on2.com>
|
Tero Rintaluoma <teror@google.com> <tero.rintaluoma@on2.com>
|
||||||
Timothy B. Terriberry <tterribe@xiph.org> <tterriberry@mozilla.com>
|
Timothy B. Terriberry <tterribe@xiph.org> Tim Terriberry <tterriberry@mozilla.com>
|
||||||
Tom Finegan <tomfinegan@google.com>
|
Tom Finegan <tomfinegan@google.com>
|
||||||
Tom Finegan <tomfinegan@google.com> <tomfinegan@chromium.org>
|
Tom Finegan <tomfinegan@google.com> <tomfinegan@chromium.org>
|
||||||
Urvang Joshi <urvang@google.com> <urvang@chromium.org>
|
|
||||||
Yaowu Xu <yaowu@google.com> <adam@xuyaowu.com>
|
|
||||||
Yaowu Xu <yaowu@google.com> <yaowu@xuyaowu.com>
|
Yaowu Xu <yaowu@google.com> <yaowu@xuyaowu.com>
|
||||||
Yaowu Xu <yaowu@google.com> <Yaowu Xu>
|
|
||||||
|
|||||||
38
AUTHORS
38
AUTHORS
@@ -3,13 +3,11 @@
|
|||||||
|
|
||||||
Aaron Watry <awatry@gmail.com>
|
Aaron Watry <awatry@gmail.com>
|
||||||
Abo Talib Mahfoodh <ab.mahfoodh@gmail.com>
|
Abo Talib Mahfoodh <ab.mahfoodh@gmail.com>
|
||||||
|
Adam Xu <adam@xuyaowu.com>
|
||||||
Adrian Grange <agrange@google.com>
|
Adrian Grange <agrange@google.com>
|
||||||
Aℓex Converse <aconverse@google.com>
|
Aℓex Converse <aconverse@google.com>
|
||||||
Ahmad Sharif <asharif@google.com>
|
Ahmad Sharif <asharif@google.com>
|
||||||
Aleksey Vasenev <margtu-fivt@ya.ru>
|
|
||||||
Alexander Potapenko <glider@google.com>
|
|
||||||
Alexander Voronov <avoronov@graphics.cs.msu.ru>
|
Alexander Voronov <avoronov@graphics.cs.msu.ru>
|
||||||
Alexandra Hájková <alexandra.khirnova@gmail.com>
|
|
||||||
Alexis Ballier <aballier@gentoo.org>
|
Alexis Ballier <aballier@gentoo.org>
|
||||||
Alok Ahuja <waveletcoeff@gmail.com>
|
Alok Ahuja <waveletcoeff@gmail.com>
|
||||||
Alpha Lam <hclam@google.com>
|
Alpha Lam <hclam@google.com>
|
||||||
@@ -17,7 +15,6 @@ A.Mahfoodh <ab.mahfoodh@gmail.com>
|
|||||||
Ami Fischman <fischman@chromium.org>
|
Ami Fischman <fischman@chromium.org>
|
||||||
Andoni Morales Alastruey <ylatuya@gmail.com>
|
Andoni Morales Alastruey <ylatuya@gmail.com>
|
||||||
Andres Mejia <mcitadel@gmail.com>
|
Andres Mejia <mcitadel@gmail.com>
|
||||||
Andrew Lewis <andrewlewis@google.com>
|
|
||||||
Andrew Russell <anrussell@google.com>
|
Andrew Russell <anrussell@google.com>
|
||||||
Angie Chiang <angiebird@google.com>
|
Angie Chiang <angiebird@google.com>
|
||||||
Aron Rosenberg <arosenberg@logitech.com>
|
Aron Rosenberg <arosenberg@logitech.com>
|
||||||
@@ -25,14 +22,10 @@ Attila Nagy <attilanagy@google.com>
|
|||||||
Brion Vibber <bvibber@wikimedia.org>
|
Brion Vibber <bvibber@wikimedia.org>
|
||||||
changjun.yang <changjun.yang@intel.com>
|
changjun.yang <changjun.yang@intel.com>
|
||||||
Charles 'Buck' Krasic <ckrasic@google.com>
|
Charles 'Buck' Krasic <ckrasic@google.com>
|
||||||
Cheng Chen <chengchen@google.com>
|
|
||||||
chm <chm@rock-chips.com>
|
chm <chm@rock-chips.com>
|
||||||
Chris Cunningham <chcunningham@chromium.org>
|
|
||||||
Christian Duvivier <cduvivier@google.com>
|
Christian Duvivier <cduvivier@google.com>
|
||||||
Daniele Castagna <dcastagna@chromium.org>
|
|
||||||
Daniel Kang <ddkang@google.com>
|
Daniel Kang <ddkang@google.com>
|
||||||
Deb Mukherjee <debargha@google.com>
|
Deb Mukherjee <debargha@google.com>
|
||||||
Deepa K G <deepa.kg@ittiam.com>
|
|
||||||
Dim Temp <dimtemp0@gmail.com>
|
Dim Temp <dimtemp0@gmail.com>
|
||||||
Dmitry Kovalev <dkovalev@google.com>
|
Dmitry Kovalev <dkovalev@google.com>
|
||||||
Dragan Mrdjan <dmrdjan@mips.com>
|
Dragan Mrdjan <dmrdjan@mips.com>
|
||||||
@@ -43,21 +36,17 @@ Fabio Pedretti <fabio.ped@libero.it>
|
|||||||
Frank Galligan <fgalligan@google.com>
|
Frank Galligan <fgalligan@google.com>
|
||||||
Fredrik Söderquist <fs@opera.com>
|
Fredrik Söderquist <fs@opera.com>
|
||||||
Fritz Koenig <frkoenig@google.com>
|
Fritz Koenig <frkoenig@google.com>
|
||||||
Gabriel Marin <gmx@chromium.org>
|
|
||||||
Gaute Strokkenes <gaute.strokkenes@broadcom.com>
|
Gaute Strokkenes <gaute.strokkenes@broadcom.com>
|
||||||
Geza Lore <gezalore@gmail.com>
|
Geza Lore <gezalore@gmail.com>
|
||||||
Ghislain MARY <ghislainmary2@gmail.com>
|
Ghislain MARY <ghislainmary2@gmail.com>
|
||||||
Giuseppe Scrivano <gscrivano@gnu.org>
|
Giuseppe Scrivano <gscrivano@gnu.org>
|
||||||
Gordana Cmiljanovic <gordana.cmiljanovic@imgtec.com>
|
Gordana Cmiljanovic <gordana.cmiljanovic@imgtec.com>
|
||||||
Gregor Jasny <gjasny@gmail.com>
|
|
||||||
Guillaume Martres <gmartres@google.com>
|
Guillaume Martres <gmartres@google.com>
|
||||||
Guillermo Ballester Valor <gbvalor@gmail.com>
|
Guillermo Ballester Valor <gbvalor@gmail.com>
|
||||||
Hangyu Kuang <hkuang@google.com>
|
Hangyu Kuang <hkuang@google.com>
|
||||||
Hanno Böck <hanno@hboeck.de>
|
Hanno Böck <hanno@hboeck.de>
|
||||||
Han Shen <shenhan@google.com>
|
|
||||||
Henrik Lundin <hlundin@google.com>
|
Henrik Lundin <hlundin@google.com>
|
||||||
Hui Su <huisu@google.com>
|
Hui Su <huisu@google.com>
|
||||||
Ivan Krasin <krasin@chromium.org>
|
|
||||||
Ivan Maltz <ivanmaltz@google.com>
|
Ivan Maltz <ivanmaltz@google.com>
|
||||||
Jacek Caban <cjacek@gmail.com>
|
Jacek Caban <cjacek@gmail.com>
|
||||||
Jacky Chen <jackychen@google.com>
|
Jacky Chen <jackychen@google.com>
|
||||||
@@ -67,13 +56,10 @@ James Zern <jzern@google.com>
|
|||||||
Jan Gerber <j@mailb.org>
|
Jan Gerber <j@mailb.org>
|
||||||
Jan Kratochvil <jan.kratochvil@redhat.com>
|
Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
Janne Salonen <jsalonen@google.com>
|
Janne Salonen <jsalonen@google.com>
|
||||||
Jean-Yves Avenard <jyavenard@mozilla.com>
|
|
||||||
Jeff Faust <jfaust@google.com>
|
Jeff Faust <jfaust@google.com>
|
||||||
Jeff Muizelaar <jmuizelaar@mozilla.com>
|
Jeff Muizelaar <jmuizelaar@mozilla.com>
|
||||||
Jeff Petkau <jpet@chromium.org>
|
Jeff Petkau <jpet@chromium.org>
|
||||||
Jerome Jiang <jianj@google.com>
|
|
||||||
Jia Jia <jia.jia@linaro.org>
|
Jia Jia <jia.jia@linaro.org>
|
||||||
Jian Zhou <zhoujian@google.com>
|
|
||||||
Jim Bankoski <jimbankoski@google.com>
|
Jim Bankoski <jimbankoski@google.com>
|
||||||
Jingning Han <jingning@google.com>
|
Jingning Han <jingning@google.com>
|
||||||
Joey Parrish <joeyparrish@google.com>
|
Joey Parrish <joeyparrish@google.com>
|
||||||
@@ -86,11 +72,8 @@ Joshua Litt <joshualitt@google.com>
|
|||||||
Julia Robson <juliamrobson@gmail.com>
|
Julia Robson <juliamrobson@gmail.com>
|
||||||
Justin Clift <justin@salasaga.org>
|
Justin Clift <justin@salasaga.org>
|
||||||
Justin Lebar <justin.lebar@gmail.com>
|
Justin Lebar <justin.lebar@gmail.com>
|
||||||
Kaustubh Raste <kaustubh.raste@imgtec.com>
|
|
||||||
KO Myung-Hun <komh@chollian.net>
|
KO Myung-Hun <komh@chollian.net>
|
||||||
Kyle Siefring <kylesiefring@gmail.com>
|
|
||||||
Lawrence Velázquez <larryv@macports.org>
|
Lawrence Velázquez <larryv@macports.org>
|
||||||
Linfeng Zhang <linfengz@google.com>
|
|
||||||
Lou Quillio <louquillio@google.com>
|
Lou Quillio <louquillio@google.com>
|
||||||
Luca Barbato <lu_zero@gentoo.org>
|
Luca Barbato <lu_zero@gentoo.org>
|
||||||
Makoto Kato <makoto.kt@gmail.com>
|
Makoto Kato <makoto.kt@gmail.com>
|
||||||
@@ -104,12 +87,8 @@ Michael Kohler <michaelkohler@live.com>
|
|||||||
Mike Frysinger <vapier@chromium.org>
|
Mike Frysinger <vapier@chromium.org>
|
||||||
Mike Hommey <mhommey@mozilla.com>
|
Mike Hommey <mhommey@mozilla.com>
|
||||||
Mikhal Shemer <mikhal@google.com>
|
Mikhal Shemer <mikhal@google.com>
|
||||||
Min Chen <chenm003@gmail.com>
|
|
||||||
Minghai Shang <minghai@google.com>
|
Minghai Shang <minghai@google.com>
|
||||||
Min Ye <yeemmi@google.com>
|
|
||||||
Moriyoshi Koizumi <mozo@mozo.jp>
|
|
||||||
Morton Jonuschat <yabawock@gmail.com>
|
Morton Jonuschat <yabawock@gmail.com>
|
||||||
Nathan E. Egge <negge@mozilla.com>
|
|
||||||
Nico Weber <thakis@chromium.org>
|
Nico Weber <thakis@chromium.org>
|
||||||
Parag Salasakar <img.mips1@gmail.com>
|
Parag Salasakar <img.mips1@gmail.com>
|
||||||
Pascal Massimino <pascal.massimino@gmail.com>
|
Pascal Massimino <pascal.massimino@gmail.com>
|
||||||
@@ -118,34 +97,24 @@ Paul Wilkins <paulwilkins@google.com>
|
|||||||
Pavol Rusnak <stick@gk2.sk>
|
Pavol Rusnak <stick@gk2.sk>
|
||||||
Paweł Hajdan <phajdan@google.com>
|
Paweł Hajdan <phajdan@google.com>
|
||||||
Pengchong Jin <pengchong@google.com>
|
Pengchong Jin <pengchong@google.com>
|
||||||
Peter Boström <pbos@chromium.org>
|
|
||||||
Peter Collingbourne <pcc@chromium.org>
|
|
||||||
Peter de Rivaz <peter.derivaz@gmail.com>
|
Peter de Rivaz <peter.derivaz@gmail.com>
|
||||||
Philip Jägenstedt <philipj@opera.com>
|
Philip Jägenstedt <philipj@opera.com>
|
||||||
Priit Laes <plaes@plaes.org>
|
Priit Laes <plaes@plaes.org>
|
||||||
Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
|
Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
|
||||||
Rafaël Carré <funman@videolan.org>
|
Rafaël Carré <funman@videolan.org>
|
||||||
Rafael de Lucena Valle <rafaeldelucena@gmail.com>
|
|
||||||
Rahul Chaudhry <rahulchaudhry@google.com>
|
|
||||||
Ralph Giles <giles@xiph.org>
|
Ralph Giles <giles@xiph.org>
|
||||||
Ranjit Kumar Tulabandu <ranjit.tulabandu@ittiam.com>
|
|
||||||
Rob Bradford <rob@linux.intel.com>
|
Rob Bradford <rob@linux.intel.com>
|
||||||
Ronald S. Bultje <rsbultje@gmail.com>
|
Ronald S. Bultje <rsbultje@gmail.com>
|
||||||
Rui Ueyama <ruiu@google.com>
|
Rui Ueyama <ruiu@google.com>
|
||||||
Sami Pietilä <samipietila@google.com>
|
Sami Pietilä <samipietila@google.com>
|
||||||
Sarah Parker <sarahparker@google.com>
|
|
||||||
Sasi Inguva <isasi@google.com>
|
|
||||||
Scott Graham <scottmg@chromium.org>
|
Scott Graham <scottmg@chromium.org>
|
||||||
Scott LaVarnway <slavarnway@google.com>
|
Scott LaVarnway <slavarnway@google.com>
|
||||||
Sean McGovern <gseanmcg@gmail.com>
|
Sean McGovern <gseanmcg@gmail.com>
|
||||||
Sergey Kolomenkin <kolomenkin@gmail.com>
|
|
||||||
Sergey Ulanov <sergeyu@chromium.org>
|
Sergey Ulanov <sergeyu@chromium.org>
|
||||||
Shimon Doodkin <helpmepro1@gmail.com>
|
Shimon Doodkin <helpmepro1@gmail.com>
|
||||||
Shiyou Yin <yinshiyou-hf@loongson.cn>
|
|
||||||
Shunyao Li <shunyaoli@google.com>
|
Shunyao Li <shunyaoli@google.com>
|
||||||
Stefan Holmer <holmer@google.com>
|
Stefan Holmer <holmer@google.com>
|
||||||
Suman Sunkara <sunkaras@google.com>
|
Suman Sunkara <sunkaras@google.com>
|
||||||
Sylvestre Ledru <sylvestre@mozilla.com>
|
|
||||||
Taekhyun Kim <takim@nvidia.com>
|
Taekhyun Kim <takim@nvidia.com>
|
||||||
Takanori MATSUURA <t.matsuu@gmail.com>
|
Takanori MATSUURA <t.matsuu@gmail.com>
|
||||||
Tamar Levy <tamar.levy@intel.com>
|
Tamar Levy <tamar.levy@intel.com>
|
||||||
@@ -155,15 +124,10 @@ Thijs Vermeir <thijsvermeir@gmail.com>
|
|||||||
Tim Kopp <tkopp@google.com>
|
Tim Kopp <tkopp@google.com>
|
||||||
Timothy B. Terriberry <tterribe@xiph.org>
|
Timothy B. Terriberry <tterribe@xiph.org>
|
||||||
Tom Finegan <tomfinegan@google.com>
|
Tom Finegan <tomfinegan@google.com>
|
||||||
Tristan Matthews <le.businessman@gmail.com>
|
|
||||||
Urvang Joshi <urvang@google.com>
|
|
||||||
Vignesh Venkatasubramanian <vigneshv@google.com>
|
Vignesh Venkatasubramanian <vigneshv@google.com>
|
||||||
Vlad Tsyrklevich <vtsyrklevich@chromium.org>
|
|
||||||
Yaowu Xu <yaowu@google.com>
|
Yaowu Xu <yaowu@google.com>
|
||||||
Yi Luo <luoyi@google.com>
|
|
||||||
Yongzhe Wang <yongzhe@google.com>
|
Yongzhe Wang <yongzhe@google.com>
|
||||||
Yunqing Wang <yunqingwang@google.com>
|
Yunqing Wang <yunqingwang@google.com>
|
||||||
Yury Gitman <yuryg@google.com>
|
|
||||||
Zoe Liu <zoeliu@google.com>
|
Zoe Liu <zoeliu@google.com>
|
||||||
Google Inc.
|
Google Inc.
|
||||||
The Mozilla Foundation
|
The Mozilla Foundation
|
||||||
|
|||||||
73
CHANGELOG
73
CHANGELOG
@@ -1,73 +1,6 @@
|
|||||||
2017-01-04 v1.7.0 "Mandarin Duck"
|
Next Release
|
||||||
This release focused on high bit depth performance (10/12 bit) and vp9
|
- Incompatible changes:
|
||||||
encoding improvements.
|
The VP9 encoder's default keyframe interval changed to 128 from 9999.
|
||||||
|
|
||||||
- Upgrading:
|
|
||||||
This release is ABI incompatible due to new vp9 encoder features.
|
|
||||||
|
|
||||||
Frame parallel decoding for vp9 has been removed.
|
|
||||||
|
|
||||||
- Enhancements:
|
|
||||||
vp9 encoding supports additional threads with --row-mt. This can be greater
|
|
||||||
than the number of tiles.
|
|
||||||
|
|
||||||
Two new vp9 encoder options have been added:
|
|
||||||
--corpus-complexity
|
|
||||||
--tune-content=film
|
|
||||||
|
|
||||||
Additional tooling for respecting the vp9 "level" profiles has been added.
|
|
||||||
|
|
||||||
- Bug fixes:
|
|
||||||
A variety of fuzzing issues.
|
|
||||||
vp8 threading fix for ARM.
|
|
||||||
Codec control VP9_SET_SKIP_LOOP_FILTER fixed.
|
|
||||||
Reject invalid multi resolution configurations.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
2015-11-09 v1.5.0 "Javan Whistling Duck"
|
2015-11-09 v1.5.0 "Javan Whistling Duck"
|
||||||
This release improves upon the VP9 encoder and speeds up the encoding and
|
This release improves upon the VP9 encoder and speeds up the encoding and
|
||||||
|
|||||||
34
README
34
README
@@ -1,4 +1,4 @@
|
|||||||
README - 24 January 2018
|
README - 23 March 2015
|
||||||
|
|
||||||
Welcome to the WebM VP8/VP9 Codec SDK!
|
Welcome to the WebM VP8/VP9 Codec SDK!
|
||||||
|
|
||||||
@@ -47,9 +47,10 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||||||
--help output of the configure script. As of this writing, the list of
|
--help output of the configure script. As of this writing, the list of
|
||||||
available targets is:
|
available targets is:
|
||||||
|
|
||||||
arm64-android-gcc
|
armv6-linux-rvct
|
||||||
|
armv6-linux-gcc
|
||||||
|
armv6-none-rvct
|
||||||
arm64-darwin-gcc
|
arm64-darwin-gcc
|
||||||
arm64-linux-gcc
|
|
||||||
armv7-android-gcc
|
armv7-android-gcc
|
||||||
armv7-darwin-gcc
|
armv7-darwin-gcc
|
||||||
armv7-linux-rvct
|
armv7-linux-rvct
|
||||||
@@ -58,13 +59,9 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||||||
armv7-win32-vs11
|
armv7-win32-vs11
|
||||||
armv7-win32-vs12
|
armv7-win32-vs12
|
||||||
armv7-win32-vs14
|
armv7-win32-vs14
|
||||||
armv7-win32-vs15
|
|
||||||
armv7s-darwin-gcc
|
armv7s-darwin-gcc
|
||||||
armv8-linux-gcc
|
|
||||||
mips32-linux-gcc
|
mips32-linux-gcc
|
||||||
mips64-linux-gcc
|
mips64-linux-gcc
|
||||||
ppc64-linux-gcc
|
|
||||||
ppc64le-linux-gcc
|
|
||||||
sparc-solaris-gcc
|
sparc-solaris-gcc
|
||||||
x86-android-gcc
|
x86-android-gcc
|
||||||
x86-darwin8-gcc
|
x86-darwin8-gcc
|
||||||
@@ -76,8 +73,6 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||||||
x86-darwin12-gcc
|
x86-darwin12-gcc
|
||||||
x86-darwin13-gcc
|
x86-darwin13-gcc
|
||||||
x86-darwin14-gcc
|
x86-darwin14-gcc
|
||||||
x86-darwin15-gcc
|
|
||||||
x86-darwin16-gcc
|
|
||||||
x86-iphonesimulator-gcc
|
x86-iphonesimulator-gcc
|
||||||
x86-linux-gcc
|
x86-linux-gcc
|
||||||
x86-linux-icc
|
x86-linux-icc
|
||||||
@@ -88,7 +83,6 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||||||
x86-win32-vs11
|
x86-win32-vs11
|
||||||
x86-win32-vs12
|
x86-win32-vs12
|
||||||
x86-win32-vs14
|
x86-win32-vs14
|
||||||
x86-win32-vs15
|
|
||||||
x86_64-android-gcc
|
x86_64-android-gcc
|
||||||
x86_64-darwin9-gcc
|
x86_64-darwin9-gcc
|
||||||
x86_64-darwin10-gcc
|
x86_64-darwin10-gcc
|
||||||
@@ -96,8 +90,6 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||||||
x86_64-darwin12-gcc
|
x86_64-darwin12-gcc
|
||||||
x86_64-darwin13-gcc
|
x86_64-darwin13-gcc
|
||||||
x86_64-darwin14-gcc
|
x86_64-darwin14-gcc
|
||||||
x86_64-darwin15-gcc
|
|
||||||
x86_64-darwin16-gcc
|
|
||||||
x86_64-iphonesimulator-gcc
|
x86_64-iphonesimulator-gcc
|
||||||
x86_64-linux-gcc
|
x86_64-linux-gcc
|
||||||
x86_64-linux-icc
|
x86_64-linux-icc
|
||||||
@@ -107,7 +99,6 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||||||
x86_64-win64-vs11
|
x86_64-win64-vs11
|
||||||
x86_64-win64-vs12
|
x86_64-win64-vs12
|
||||||
x86_64-win64-vs14
|
x86_64-win64-vs14
|
||||||
x86_64-win64-vs15
|
|
||||||
generic-gnu
|
generic-gnu
|
||||||
|
|
||||||
The generic-gnu target, in conjunction with the CROSS environment variable,
|
The generic-gnu target, in conjunction with the CROSS environment variable,
|
||||||
@@ -136,22 +127,7 @@ VP8/VP9 TEST VECTORS:
|
|||||||
$ ./configure --enable-unit-tests
|
$ ./configure --enable-unit-tests
|
||||||
$ LIBVPX_TEST_DATA_PATH=../libvpx-test-data make testdata
|
$ LIBVPX_TEST_DATA_PATH=../libvpx-test-data make testdata
|
||||||
|
|
||||||
CODE STYLE:
|
|
||||||
The coding style used by this project is enforced with clang-format using the
|
|
||||||
configuration contained in the .clang-format file in the root of the
|
|
||||||
repository.
|
|
||||||
|
|
||||||
Before pushing changes for review you can format your code with:
|
|
||||||
# Apply clang-format to modified .c, .h and .cc files
|
|
||||||
$ clang-format -i --style=file \
|
|
||||||
$(git diff --name-only --diff-filter=ACMR '*.[hc]' '*.cc')
|
|
||||||
|
|
||||||
Check the .clang-format file for the version used to generate it if there is
|
|
||||||
any difference between your local formatting and the review system.
|
|
||||||
|
|
||||||
See also: http://clang.llvm.org/docs/ClangFormat.html
|
|
||||||
|
|
||||||
SUPPORT
|
SUPPORT
|
||||||
This library is an open source project supported by its community. Please
|
This library is an open source project supported by its community. Please
|
||||||
email webm-discuss@webmproject.org for help.
|
please email webm-discuss@webmproject.org for help.
|
||||||
|
|
||||||
|
|||||||
101
args.c
101
args.c
@@ -8,12 +8,12 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include "args.h"
|
#include "args.h"
|
||||||
|
|
||||||
#include "vpx/vpx_integer.h"
|
|
||||||
#include "vpx_ports/msvc.h"
|
#include "vpx_ports/msvc.h"
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__
|
#if defined(__GNUC__) && __GNUC__
|
||||||
@@ -22,6 +22,7 @@ extern void die(const char *fmt, ...) __attribute__((noreturn));
|
|||||||
extern void die(const char *fmt, ...);
|
extern void die(const char *fmt, ...);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct arg arg_init(char **argv) {
|
struct arg arg_init(char **argv) {
|
||||||
struct arg a;
|
struct arg a;
|
||||||
|
|
||||||
@@ -36,22 +37,27 @@ struct arg arg_init(char **argv) {
|
|||||||
int arg_match(struct arg *arg_, const struct arg_def *def, char **argv) {
|
int arg_match(struct arg *arg_, const struct arg_def *def, char **argv) {
|
||||||
struct arg arg;
|
struct arg arg;
|
||||||
|
|
||||||
if (!argv[0] || argv[0][0] != '-') return 0;
|
if (!argv[0] || argv[0][0] != '-')
|
||||||
|
return 0;
|
||||||
|
|
||||||
arg = arg_init(argv);
|
arg = arg_init(argv);
|
||||||
|
|
||||||
if (def->short_name && strlen(arg.argv[0]) == strlen(def->short_name) + 1 &&
|
if (def->short_name
|
||||||
!strcmp(arg.argv[0] + 1, def->short_name)) {
|
&& strlen(arg.argv[0]) == strlen(def->short_name) + 1
|
||||||
|
&& !strcmp(arg.argv[0] + 1, def->short_name)) {
|
||||||
|
|
||||||
arg.name = arg.argv[0] + 1;
|
arg.name = arg.argv[0] + 1;
|
||||||
arg.val = def->has_val ? arg.argv[1] : NULL;
|
arg.val = def->has_val ? arg.argv[1] : NULL;
|
||||||
arg.argv_step = def->has_val ? 2 : 1;
|
arg.argv_step = def->has_val ? 2 : 1;
|
||||||
} else if (def->long_name) {
|
} else if (def->long_name) {
|
||||||
const size_t name_len = strlen(def->long_name);
|
const size_t name_len = strlen(def->long_name);
|
||||||
|
|
||||||
if (strlen(arg.argv[0]) >= name_len + 2 && arg.argv[0][1] == '-' &&
|
if (strlen(arg.argv[0]) >= name_len + 2
|
||||||
!strncmp(arg.argv[0] + 2, def->long_name, name_len) &&
|
&& arg.argv[0][1] == '-'
|
||||||
(arg.argv[0][name_len + 2] == '=' ||
|
&& !strncmp(arg.argv[0] + 2, def->long_name, name_len)
|
||||||
arg.argv[0][name_len + 2] == '\0')) {
|
&& (arg.argv[0][name_len + 2] == '='
|
||||||
|
|| arg.argv[0][name_len + 2] == '\0')) {
|
||||||
|
|
||||||
arg.name = arg.argv[0] + 2;
|
arg.name = arg.argv[0] + 2;
|
||||||
arg.val = arg.name[name_len] == '=' ? arg.name + name_len + 1 : NULL;
|
arg.val = arg.name[name_len] == '=' ? arg.name + name_len + 1 : NULL;
|
||||||
arg.argv_step = 1;
|
arg.argv_step = 1;
|
||||||
@@ -64,7 +70,8 @@ int arg_match(struct arg *arg_, const struct arg_def *def, char **argv) {
|
|||||||
if (arg.name && arg.val && !def->has_val)
|
if (arg.name && arg.val && !def->has_val)
|
||||||
die("Error: option %s requires no argument.\n", arg.name);
|
die("Error: option %s requires no argument.\n", arg.name);
|
||||||
|
|
||||||
if (arg.name && (arg.val || !def->has_val)) {
|
if (arg.name
|
||||||
|
&& (arg.val || !def->has_val)) {
|
||||||
arg.def = def;
|
arg.def = def;
|
||||||
*arg_ = arg;
|
*arg_ = arg;
|
||||||
return 1;
|
return 1;
|
||||||
@@ -73,12 +80,15 @@ int arg_match(struct arg *arg_, const struct arg_def *def, char **argv) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *arg_next(struct arg *arg) {
|
const char *arg_next(struct arg *arg) {
|
||||||
if (arg->argv[0]) arg->argv += arg->argv_step;
|
if (arg->argv[0])
|
||||||
|
arg->argv += arg->argv_step;
|
||||||
|
|
||||||
return *arg->argv;
|
return *arg->argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char **argv_dup(int argc, const char **argv) {
|
char **argv_dup(int argc, const char **argv) {
|
||||||
char **new_argv = malloc((argc + 1) * sizeof(*argv));
|
char **new_argv = malloc((argc + 1) * sizeof(*argv));
|
||||||
|
|
||||||
@@ -87,6 +97,7 @@ char **argv_dup(int argc, const char **argv) {
|
|||||||
return new_argv;
|
return new_argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void arg_show_usage(FILE *fp, const struct arg_def *const *defs) {
|
void arg_show_usage(FILE *fp, const struct arg_def *const *defs) {
|
||||||
char option_text[40] = {0};
|
char option_text[40] = {0};
|
||||||
|
|
||||||
@@ -98,12 +109,15 @@ void arg_show_usage(FILE *fp, const struct arg_def *const *defs) {
|
|||||||
if (def->short_name && def->long_name) {
|
if (def->short_name && def->long_name) {
|
||||||
char *comma = def->has_val ? "," : ", ";
|
char *comma = def->has_val ? "," : ", ";
|
||||||
|
|
||||||
snprintf(option_text, 37, "-%s%s%s --%s%6s", def->short_name, short_val,
|
snprintf(option_text, 37, "-%s%s%s --%s%6s",
|
||||||
comma, def->long_name, long_val);
|
def->short_name, short_val, comma,
|
||||||
|
def->long_name, long_val);
|
||||||
} else if (def->short_name)
|
} else if (def->short_name)
|
||||||
snprintf(option_text, 37, "-%s%s", def->short_name, short_val);
|
snprintf(option_text, 37, "-%s%s",
|
||||||
|
def->short_name, short_val);
|
||||||
else if (def->long_name)
|
else if (def->long_name)
|
||||||
snprintf(option_text, 37, " --%s%s", def->long_name, long_val);
|
snprintf(option_text, 37, " --%s%s",
|
||||||
|
def->long_name, long_val);
|
||||||
|
|
||||||
fprintf(fp, " %-37s\t%s\n", option_text, def->desc);
|
fprintf(fp, " %-37s\t%s\n", option_text, def->desc);
|
||||||
|
|
||||||
@@ -113,45 +127,51 @@ void arg_show_usage(FILE *fp, const struct arg_def *const *defs) {
|
|||||||
fprintf(fp, " %-37s\t ", "");
|
fprintf(fp, " %-37s\t ", "");
|
||||||
|
|
||||||
for (listptr = def->enums; listptr->name; listptr++)
|
for (listptr = def->enums; listptr->name; listptr++)
|
||||||
fprintf(fp, "%s%s", listptr->name, listptr[1].name ? ", " : "\n");
|
fprintf(fp, "%s%s", listptr->name,
|
||||||
|
listptr[1].name ? ", " : "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int arg_parse_uint(const struct arg *arg) {
|
unsigned int arg_parse_uint(const struct arg *arg) {
|
||||||
uint32_t rawval;
|
long int rawval;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
|
||||||
rawval = (uint32_t)strtoul(arg->val, &endptr, 10);
|
rawval = strtol(arg->val, &endptr, 10);
|
||||||
|
|
||||||
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
||||||
if (rawval <= UINT_MAX) return rawval;
|
if (rawval >= 0 && rawval <= UINT_MAX)
|
||||||
|
return rawval;
|
||||||
|
|
||||||
die("Option %s: Value %ld out of range for unsigned int\n", arg->name,
|
die("Option %s: Value %ld out of range for unsigned int\n",
|
||||||
rawval);
|
arg->name, rawval);
|
||||||
}
|
}
|
||||||
|
|
||||||
die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
|
die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int arg_parse_int(const struct arg *arg) {
|
int arg_parse_int(const struct arg *arg) {
|
||||||
int32_t rawval;
|
long int rawval;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
|
||||||
rawval = (int32_t)strtol(arg->val, &endptr, 10);
|
rawval = strtol(arg->val, &endptr, 10);
|
||||||
|
|
||||||
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
||||||
if (rawval >= INT_MIN && rawval <= INT_MAX) return (int)rawval;
|
if (rawval >= INT_MIN && rawval <= INT_MAX)
|
||||||
|
return rawval;
|
||||||
|
|
||||||
die("Option %s: Value %ld out of range for signed int\n", arg->name,
|
die("Option %s: Value %ld out of range for signed int\n",
|
||||||
rawval);
|
arg->name, rawval);
|
||||||
}
|
}
|
||||||
|
|
||||||
die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
|
die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct vpx_rational {
|
struct vpx_rational {
|
||||||
int num; /**< fraction numerator */
|
int num; /**< fraction numerator */
|
||||||
int den; /**< fraction denominator */
|
int den; /**< fraction denominator */
|
||||||
@@ -166,28 +186,25 @@ struct vpx_rational arg_parse_rational(const struct arg *arg) {
|
|||||||
|
|
||||||
if (arg->val[0] != '\0' && endptr[0] == '/') {
|
if (arg->val[0] != '\0' && endptr[0] == '/') {
|
||||||
if (rawval >= INT_MIN && rawval <= INT_MAX)
|
if (rawval >= INT_MIN && rawval <= INT_MAX)
|
||||||
rat.num = (int)rawval;
|
rat.num = rawval;
|
||||||
else
|
else die("Option %s: Value %ld out of range for signed int\n",
|
||||||
die("Option %s: Value %ld out of range for signed int\n", arg->name,
|
arg->name, rawval);
|
||||||
rawval);
|
} else die("Option %s: Expected / at '%c'\n", arg->name, *endptr);
|
||||||
} else
|
|
||||||
die("Option %s: Expected / at '%c'\n", arg->name, *endptr);
|
|
||||||
|
|
||||||
/* parse denominator */
|
/* parse denominator */
|
||||||
rawval = strtol(endptr + 1, &endptr, 10);
|
rawval = strtol(endptr + 1, &endptr, 10);
|
||||||
|
|
||||||
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
||||||
if (rawval >= INT_MIN && rawval <= INT_MAX)
|
if (rawval >= INT_MIN && rawval <= INT_MAX)
|
||||||
rat.den = (int)rawval;
|
rat.den = rawval;
|
||||||
else
|
else die("Option %s: Value %ld out of range for signed int\n",
|
||||||
die("Option %s: Value %ld out of range for signed int\n", arg->name,
|
arg->name, rawval);
|
||||||
rawval);
|
} else die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
|
||||||
} else
|
|
||||||
die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
|
|
||||||
|
|
||||||
return rat;
|
return rat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int arg_parse_enum(const struct arg *arg) {
|
int arg_parse_enum(const struct arg *arg) {
|
||||||
const struct arg_enum_list *listptr;
|
const struct arg_enum_list *listptr;
|
||||||
long int rawval;
|
long int rawval;
|
||||||
@@ -198,18 +215,22 @@ int arg_parse_enum(const struct arg *arg) {
|
|||||||
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
||||||
/* Got a raw value, make sure it's valid */
|
/* Got a raw value, make sure it's valid */
|
||||||
for (listptr = arg->def->enums; listptr->name; listptr++)
|
for (listptr = arg->def->enums; listptr->name; listptr++)
|
||||||
if (listptr->val == rawval) return (int)rawval;
|
if (listptr->val == rawval)
|
||||||
|
return rawval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Next see if it can be parsed as a string */
|
/* Next see if it can be parsed as a string */
|
||||||
for (listptr = arg->def->enums; listptr->name; listptr++)
|
for (listptr = arg->def->enums; listptr->name; listptr++)
|
||||||
if (!strcmp(arg->val, listptr->name)) return listptr->val;
|
if (!strcmp(arg->val, listptr->name))
|
||||||
|
return listptr->val;
|
||||||
|
|
||||||
die("Option %s: Invalid value '%s'\n", arg->name, arg->val);
|
die("Option %s: Invalid value '%s'\n", arg->name, arg->val);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int arg_parse_enum_or_int(const struct arg *arg) {
|
int arg_parse_enum_or_int(const struct arg *arg) {
|
||||||
if (arg->def->enums) return arg_parse_enum(arg);
|
if (arg->def->enums)
|
||||||
|
return arg_parse_enum(arg);
|
||||||
return arg_parse_int(arg);
|
return arg_parse_int(arg);
|
||||||
}
|
}
|
||||||
|
|||||||
13
args.h
13
args.h
@@ -8,6 +8,7 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef ARGS_H_
|
#ifndef ARGS_H_
|
||||||
#define ARGS_H_
|
#define ARGS_H_
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -28,8 +29,7 @@ struct arg_enum_list {
|
|||||||
const char *name;
|
const char *name;
|
||||||
int val;
|
int val;
|
||||||
};
|
};
|
||||||
#define ARG_ENUM_LIST_END \
|
#define ARG_ENUM_LIST_END {0}
|
||||||
{ 0 }
|
|
||||||
|
|
||||||
typedef struct arg_def {
|
typedef struct arg_def {
|
||||||
const char *short_name;
|
const char *short_name;
|
||||||
@@ -38,12 +38,9 @@ typedef struct arg_def {
|
|||||||
const char *desc;
|
const char *desc;
|
||||||
const struct arg_enum_list *enums;
|
const struct arg_enum_list *enums;
|
||||||
} arg_def_t;
|
} arg_def_t;
|
||||||
#define ARG_DEF(s, l, v, d) \
|
#define ARG_DEF(s,l,v,d) {s,l,v,d, NULL}
|
||||||
{ s, l, v, d, NULL }
|
#define ARG_DEF_ENUM(s,l,v,d,e) {s,l,v,d,e}
|
||||||
#define ARG_DEF_ENUM(s, l, v, d, e) \
|
#define ARG_DEF_LIST_END {0}
|
||||||
{ s, l, v, d, e }
|
|
||||||
#define ARG_DEF_LIST_END \
|
|
||||||
{ 0 }
|
|
||||||
|
|
||||||
struct arg arg_init(char **argv);
|
struct arg arg_init(char **argv);
|
||||||
int arg_match(struct arg *arg_, const struct arg_def *def, char **argv);
|
int arg_match(struct arg *arg_, const struct arg_def *def, char **argv);
|
||||||
|
|||||||
@@ -29,6 +29,11 @@
|
|||||||
# include $(CLEAR_VARS)
|
# include $(CLEAR_VARS)
|
||||||
# include jni/libvpx/build/make/Android.mk
|
# include jni/libvpx/build/make/Android.mk
|
||||||
#
|
#
|
||||||
|
# There are currently two TARGET_ARCH_ABI targets for ARM.
|
||||||
|
# armeabi and armeabi-v7a. armeabi-v7a is selected by creating an
|
||||||
|
# Application.mk in the jni directory that contains:
|
||||||
|
# APP_ABI := armeabi-v7a
|
||||||
|
#
|
||||||
# By default libvpx will detect at runtime the existance of NEON extension.
|
# By default libvpx will detect at runtime the existance of NEON extension.
|
||||||
# For this we import the 'cpufeatures' module from the NDK sources.
|
# For this we import the 'cpufeatures' module from the NDK sources.
|
||||||
# libvpx can also be configured without this runtime detection method.
|
# libvpx can also be configured without this runtime detection method.
|
||||||
@@ -37,44 +42,28 @@
|
|||||||
# --disable-neon-asm
|
# --disable-neon-asm
|
||||||
# will remove any NEON dependency.
|
# will remove any NEON dependency.
|
||||||
|
|
||||||
|
# To change to building armeabi, run ./libvpx/configure again, but with
|
||||||
|
# --target=armv6-android-gcc and modify the Application.mk file to
|
||||||
|
# set APP_ABI := armeabi
|
||||||
#
|
#
|
||||||
# Running ndk-build will build libvpx and include it in your project.
|
# Running ndk-build will build libvpx and include it in your project.
|
||||||
#
|
#
|
||||||
|
|
||||||
# Alternatively, building the examples and unit tests can be accomplished in the
|
|
||||||
# following way:
|
|
||||||
#
|
|
||||||
# Create a standalone toolchain from the NDK:
|
|
||||||
# https://developer.android.com/ndk/guides/standalone_toolchain.html
|
|
||||||
#
|
|
||||||
# For example - to test on arm64 devices with clang:
|
|
||||||
# $NDK/build/tools/make_standalone_toolchain.py \
|
|
||||||
# --arch arm64 --install-dir=/tmp/my-android-toolchain
|
|
||||||
# export PATH=/tmp/my-android-toolchain/bin:$PATH
|
|
||||||
# CROSS=aarch64-linux-android- CC=clang CXX=clang++ /path/to/libvpx/configure \
|
|
||||||
# --target=arm64-android-gcc
|
|
||||||
#
|
|
||||||
# Push the resulting binaries to a device and run them:
|
|
||||||
# adb push test_libvpx /data/tmp/test_libvpx
|
|
||||||
# adb shell /data/tmp/test_libvpx --gtest_filter=\*Sixtap\*
|
|
||||||
#
|
|
||||||
# Make sure to push the test data as well and set LIBVPX_TEST_DATA
|
|
||||||
|
|
||||||
CONFIG_DIR := $(LOCAL_PATH)/
|
CONFIG_DIR := $(LOCAL_PATH)/
|
||||||
LIBVPX_PATH := $(LOCAL_PATH)/libvpx
|
LIBVPX_PATH := $(LOCAL_PATH)/libvpx
|
||||||
ASM_CNV_PATH_LOCAL := $(TARGET_ARCH_ABI)/ads2gas
|
ASM_CNV_PATH_LOCAL := $(TARGET_ARCH_ABI)/ads2gas
|
||||||
ASM_CNV_PATH := $(LOCAL_PATH)/$(ASM_CNV_PATH_LOCAL)
|
ASM_CNV_PATH := $(LOCAL_PATH)/$(ASM_CNV_PATH_LOCAL)
|
||||||
ifneq ($(V),1)
|
|
||||||
qexec := @
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Use the makefiles generated by upstream configure to determine which files to
|
# Use the makefiles generated by upstream configure to determine which files to
|
||||||
# build. Also set any architecture-specific flags.
|
# build. Also set any architecture-specific flags.
|
||||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||||
include $(CONFIG_DIR)libs-armv7-android-gcc.mk
|
include $(CONFIG_DIR)libs-armv7-android-gcc.mk
|
||||||
LOCAL_ARM_MODE := arm
|
LOCAL_ARM_MODE := arm
|
||||||
|
else ifeq ($(TARGET_ARCH_ABI),armeabi)
|
||||||
|
include $(CONFIG_DIR)libs-armv6-android-gcc.mk
|
||||||
|
LOCAL_ARM_MODE := arm
|
||||||
else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
|
else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
|
||||||
include $(CONFIG_DIR)libs-arm64-android-gcc.mk
|
include $(CONFIG_DIR)libs-armv8-android-gcc.mk
|
||||||
LOCAL_ARM_MODE := arm
|
LOCAL_ARM_MODE := arm
|
||||||
else ifeq ($(TARGET_ARCH_ABI),x86)
|
else ifeq ($(TARGET_ARCH_ABI),x86)
|
||||||
include $(CONFIG_DIR)libs-x86-android-gcc.mk
|
include $(CONFIG_DIR)libs-x86-android-gcc.mk
|
||||||
@@ -104,10 +93,10 @@ LOCAL_CFLAGS := -O3
|
|||||||
# like x86inc.asm and x86_abi_support.asm
|
# like x86inc.asm and x86_abi_support.asm
|
||||||
LOCAL_ASMFLAGS := -I$(LIBVPX_PATH)
|
LOCAL_ASMFLAGS := -I$(LIBVPX_PATH)
|
||||||
|
|
||||||
.PRECIOUS: %.asm.S
|
.PRECIOUS: %.asm.s
|
||||||
$(ASM_CNV_PATH)/libvpx/%.asm.S: $(LIBVPX_PATH)/%.asm
|
$(ASM_CNV_PATH)/libvpx/%.asm.s: $(LIBVPX_PATH)/%.asm
|
||||||
$(qexec)mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
$(qexec)$(CONFIG_DIR)$(ASM_CONVERSION) <$< > $@
|
@$(CONFIG_DIR)$(ASM_CONVERSION) <$< > $@
|
||||||
|
|
||||||
# For building *_rtcd.h, which have rules in libs.mk
|
# For building *_rtcd.h, which have rules in libs.mk
|
||||||
TGT_ISA:=$(word 1, $(subst -, ,$(TOOLCHAIN)))
|
TGT_ISA:=$(word 1, $(subst -, ,$(TOOLCHAIN)))
|
||||||
@@ -135,7 +124,7 @@ endif
|
|||||||
|
|
||||||
# Pull out assembly files, splitting NEON from the rest. This is
|
# Pull out assembly files, splitting NEON from the rest. This is
|
||||||
# done to specify that the NEON assembly files use NEON assembler flags.
|
# done to specify that the NEON assembly files use NEON assembler flags.
|
||||||
# x86 assembly matches %.asm, arm matches %.asm.S
|
# x86 assembly matches %.asm, arm matches %.asm.s
|
||||||
|
|
||||||
# x86:
|
# x86:
|
||||||
|
|
||||||
@@ -143,44 +132,31 @@ CODEC_SRCS_ASM_X86 = $(filter %.asm, $(CODEC_SRCS_UNIQUE))
|
|||||||
LOCAL_SRC_FILES += $(foreach file, $(CODEC_SRCS_ASM_X86), libvpx/$(file))
|
LOCAL_SRC_FILES += $(foreach file, $(CODEC_SRCS_ASM_X86), libvpx/$(file))
|
||||||
|
|
||||||
# arm:
|
# arm:
|
||||||
CODEC_SRCS_ASM_ARM_ALL = $(filter %.asm.S, $(CODEC_SRCS_UNIQUE))
|
CODEC_SRCS_ASM_ARM_ALL = $(filter %.asm.s, $(CODEC_SRCS_UNIQUE))
|
||||||
CODEC_SRCS_ASM_ARM = $(foreach v, \
|
CODEC_SRCS_ASM_ARM = $(foreach v, \
|
||||||
$(CODEC_SRCS_ASM_ARM_ALL), \
|
$(CODEC_SRCS_ASM_ARM_ALL), \
|
||||||
$(if $(findstring neon,$(v)),,$(v)))
|
$(if $(findstring neon,$(v)),,$(v)))
|
||||||
CODEC_SRCS_ASM_ADS2GAS = $(patsubst %.S, \
|
CODEC_SRCS_ASM_ADS2GAS = $(patsubst %.s, \
|
||||||
$(ASM_CNV_PATH_LOCAL)/libvpx/%.S, \
|
$(ASM_CNV_PATH_LOCAL)/libvpx/%.s, \
|
||||||
$(CODEC_SRCS_ASM_ARM))
|
$(CODEC_SRCS_ASM_ARM))
|
||||||
LOCAL_SRC_FILES += $(CODEC_SRCS_ASM_ADS2GAS)
|
LOCAL_SRC_FILES += $(CODEC_SRCS_ASM_ADS2GAS)
|
||||||
|
|
||||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||||
ASM_INCLUDES := vpx_dsp/arm/idct_neon.asm.S
|
|
||||||
CODEC_SRCS_ASM_NEON = $(foreach v, \
|
CODEC_SRCS_ASM_NEON = $(foreach v, \
|
||||||
$(CODEC_SRCS_ASM_ARM_ALL),\
|
$(CODEC_SRCS_ASM_ARM_ALL),\
|
||||||
$(if $(findstring neon,$(v)),$(v),))
|
$(if $(findstring neon,$(v)),$(v),))
|
||||||
CODEC_SRCS_ASM_NEON := $(filter-out $(addprefix %, $(ASM_INCLUDES)), \
|
CODEC_SRCS_ASM_NEON_ADS2GAS = $(patsubst %.s, \
|
||||||
|
$(ASM_CNV_PATH_LOCAL)/libvpx/%.s, \
|
||||||
$(CODEC_SRCS_ASM_NEON))
|
$(CODEC_SRCS_ASM_NEON))
|
||||||
CODEC_SRCS_ASM_NEON_ADS2GAS = $(patsubst %.S, \
|
LOCAL_SRC_FILES += $(patsubst %.s, \
|
||||||
$(ASM_CNV_PATH_LOCAL)/libvpx/%.S, \
|
%.s.neon, \
|
||||||
$(CODEC_SRCS_ASM_NEON))
|
|
||||||
LOCAL_SRC_FILES += $(patsubst %.S, \
|
|
||||||
%.S.neon, \
|
|
||||||
$(CODEC_SRCS_ASM_NEON_ADS2GAS))
|
$(CODEC_SRCS_ASM_NEON_ADS2GAS))
|
||||||
|
|
||||||
NEON_ASM_TARGETS = $(patsubst %.S, \
|
|
||||||
$(ASM_CNV_PATH)/libvpx/%.S, \
|
|
||||||
$(CODEC_SRCS_ASM_NEON))
|
|
||||||
# add a dependency to the full path to the ads2gas output to ensure the
|
|
||||||
# includes are converted first.
|
|
||||||
ifneq ($(strip $(NEON_ASM_TARGETS)),)
|
|
||||||
$(NEON_ASM_TARGETS): $(addprefix $(ASM_CNV_PATH)/libvpx/, $(ASM_INCLUDES))
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LOCAL_CFLAGS += \
|
LOCAL_CFLAGS += \
|
||||||
-DHAVE_CONFIG_H=vpx_config.h \
|
-DHAVE_CONFIG_H=vpx_config.h \
|
||||||
-I$(LIBVPX_PATH) \
|
-I$(LIBVPX_PATH) \
|
||||||
-I$(ASM_CNV_PATH) \
|
-I$(ASM_CNV_PATH)
|
||||||
-I$(ASM_CNV_PATH)/libvpx
|
|
||||||
|
|
||||||
LOCAL_MODULE := libvpx
|
LOCAL_MODULE := libvpx
|
||||||
|
|
||||||
@@ -192,17 +168,13 @@ endif
|
|||||||
define rtcd_dep_template
|
define rtcd_dep_template
|
||||||
rtcd_dep_template_SRCS := $(addprefix $(LOCAL_PATH)/, $(LOCAL_SRC_FILES))
|
rtcd_dep_template_SRCS := $(addprefix $(LOCAL_PATH)/, $(LOCAL_SRC_FILES))
|
||||||
rtcd_dep_template_SRCS := $$(rtcd_dep_template_SRCS:.neon=)
|
rtcd_dep_template_SRCS := $$(rtcd_dep_template_SRCS:.neon=)
|
||||||
ifeq ($(CONFIG_VP8), yes)
|
ifeq ($(CONFIG_VP10), yes)
|
||||||
$$(rtcd_dep_template_SRCS): vp8_rtcd.h
|
$$(rtcd_dep_template_SRCS): vp10_rtcd.h
|
||||||
endif
|
|
||||||
ifeq ($(CONFIG_VP9), yes)
|
|
||||||
$$(rtcd_dep_template_SRCS): vp9_rtcd.h
|
|
||||||
endif
|
endif
|
||||||
$$(rtcd_dep_template_SRCS): vpx_scale_rtcd.h
|
$$(rtcd_dep_template_SRCS): vpx_scale_rtcd.h
|
||||||
$$(rtcd_dep_template_SRCS): vpx_dsp_rtcd.h
|
$$(rtcd_dep_template_SRCS): vpx_dsp_rtcd.h
|
||||||
|
|
||||||
rtcd_dep_template_CONFIG_ASM_ABIS := x86 x86_64 armeabi-v7a
|
ifneq ($(findstring $(TARGET_ARCH_ABI),x86 x86_64),)
|
||||||
ifneq ($$(findstring $(TARGET_ARCH_ABI),$$(rtcd_dep_template_CONFIG_ASM_ABIS)),)
|
|
||||||
$$(rtcd_dep_template_SRCS): vpx_config.asm
|
$$(rtcd_dep_template_SRCS): vpx_config.asm
|
||||||
endif
|
endif
|
||||||
endef
|
endef
|
||||||
@@ -212,17 +184,16 @@ $(eval $(call rtcd_dep_template))
|
|||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
@echo "Clean: ads2gas files [$(TARGET_ARCH_ABI)]"
|
@echo "Clean: ads2gas files [$(TARGET_ARCH_ABI)]"
|
||||||
$(qexec)$(RM) $(CODEC_SRCS_ASM_ADS2GAS) $(CODEC_SRCS_ASM_NEON_ADS2GAS)
|
@$(RM) $(CODEC_SRCS_ASM_ADS2GAS) $(CODEC_SRCS_ASM_NEON_ADS2GAS)
|
||||||
$(qexec)$(RM) -r $(ASM_CNV_PATH)
|
@$(RM) -r $(ASM_CNV_PATH)
|
||||||
$(qexec)$(RM) $(CLEAN-OBJS)
|
@$(RM) $(CLEAN-OBJS)
|
||||||
|
|
||||||
ifeq ($(ENABLE_SHARED),1)
|
ifeq ($(ENABLE_SHARED),1)
|
||||||
LOCAL_CFLAGS += -fPIC
|
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
else
|
else
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes)
|
ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes)
|
||||||
$(call import-module,android/cpufeatures)
|
$(call import-module,cpufeatures)
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ all:
|
|||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean::
|
clean::
|
||||||
rm -f $(OBJS-yes) $(OBJS-yes:.o=.d) $(OBJS-yes:.asm.S.o=.asm.S)
|
rm -f $(OBJS-yes) $(OBJS-yes:.o=.d) $(OBJS-yes:.asm.s.o=.asm.s)
|
||||||
rm -f $(CLEAN-OBJS)
|
rm -f $(CLEAN-OBJS)
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
@@ -124,7 +124,6 @@ ifeq ($(TOOLCHAIN), x86-os2-gcc)
|
|||||||
CFLAGS += -mstackrealign
|
CFLAGS += -mstackrealign
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# x86[_64]
|
|
||||||
$(BUILD_PFX)%_mmx.c.d: CFLAGS += -mmmx
|
$(BUILD_PFX)%_mmx.c.d: CFLAGS += -mmmx
|
||||||
$(BUILD_PFX)%_mmx.c.o: CFLAGS += -mmmx
|
$(BUILD_PFX)%_mmx.c.o: CFLAGS += -mmmx
|
||||||
$(BUILD_PFX)%_sse2.c.d: CFLAGS += -msse2
|
$(BUILD_PFX)%_sse2.c.d: CFLAGS += -msse2
|
||||||
@@ -139,12 +138,6 @@ $(BUILD_PFX)%_avx.c.d: CFLAGS += -mavx
|
|||||||
$(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx
|
$(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx
|
||||||
$(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2
|
$(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2
|
||||||
$(BUILD_PFX)%_avx2.c.o: CFLAGS += -mavx2
|
$(BUILD_PFX)%_avx2.c.o: CFLAGS += -mavx2
|
||||||
$(BUILD_PFX)%_avx512.c.d: CFLAGS += -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl
|
|
||||||
$(BUILD_PFX)%_avx512.c.o: CFLAGS += -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl
|
|
||||||
|
|
||||||
# POWER
|
|
||||||
$(BUILD_PFX)%_vsx.c.d: CFLAGS += -maltivec -mvsx
|
|
||||||
$(BUILD_PFX)%_vsx.c.o: CFLAGS += -maltivec -mvsx
|
|
||||||
|
|
||||||
$(BUILD_PFX)%.c.d: %.c
|
$(BUILD_PFX)%.c.d: %.c
|
||||||
$(if $(quiet),@echo " [DEP] $@")
|
$(if $(quiet),@echo " [DEP] $@")
|
||||||
@@ -187,13 +180,13 @@ $(BUILD_PFX)%.asm.o: %.asm
|
|||||||
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
||||||
$(qexec)$(AS) $(ASFLAGS) -o $@ $<
|
$(qexec)$(AS) $(ASFLAGS) -o $@ $<
|
||||||
|
|
||||||
$(BUILD_PFX)%.S.d: %.S
|
$(BUILD_PFX)%.s.d: %.s
|
||||||
$(if $(quiet),@echo " [DEP] $@")
|
$(if $(quiet),@echo " [DEP] $@")
|
||||||
$(qexec)mkdir -p $(dir $@)
|
$(qexec)mkdir -p $(dir $@)
|
||||||
$(qexec)$(SRC_PATH_BARE)/build/make/gen_asm_deps.sh \
|
$(qexec)$(SRC_PATH_BARE)/build/make/gen_asm_deps.sh \
|
||||||
--build-pfx=$(BUILD_PFX) --depfile=$@ $(ASFLAGS) $< > $@
|
--build-pfx=$(BUILD_PFX) --depfile=$@ $(ASFLAGS) $< > $@
|
||||||
|
|
||||||
$(BUILD_PFX)%.S.o: %.S
|
$(BUILD_PFX)%.s.o: %.s
|
||||||
$(if $(quiet),@echo " [AS] $@")
|
$(if $(quiet),@echo " [AS] $@")
|
||||||
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
||||||
$(qexec)$(AS) $(ASFLAGS) -o $@ $<
|
$(qexec)$(AS) $(ASFLAGS) -o $@ $<
|
||||||
@@ -205,8 +198,8 @@ $(BUILD_PFX)%.c.S: %.c
|
|||||||
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
||||||
$(qexec)$(CC) -S $(CFLAGS) -o $@ $<
|
$(qexec)$(CC) -S $(CFLAGS) -o $@ $<
|
||||||
|
|
||||||
.PRECIOUS: %.asm.S
|
.PRECIOUS: %.asm.s
|
||||||
$(BUILD_PFX)%.asm.S: %.asm
|
$(BUILD_PFX)%.asm.s: %.asm
|
||||||
$(if $(quiet),@echo " [ASM CONVERSION] $@")
|
$(if $(quiet),@echo " [ASM CONVERSION] $@")
|
||||||
$(qexec)mkdir -p $(dir $@)
|
$(qexec)mkdir -p $(dir $@)
|
||||||
$(qexec)$(ASM_CONVERSION) <$< >$@
|
$(qexec)$(ASM_CONVERSION) <$< >$@
|
||||||
|
|||||||
@@ -138,6 +138,14 @@ while (<STDIN>)
|
|||||||
s/DCD(.*)/.long $1/;
|
s/DCD(.*)/.long $1/;
|
||||||
s/DCB(.*)/.byte $1/;
|
s/DCB(.*)/.byte $1/;
|
||||||
|
|
||||||
|
# RN to .req
|
||||||
|
if (s/RN\s+([Rr]\d+|lr)/.req $1/)
|
||||||
|
{
|
||||||
|
print;
|
||||||
|
print "$comment_sub$comment\n" if defined $comment;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
# Make function visible to linker, and make additional symbol with
|
# Make function visible to linker, and make additional symbol with
|
||||||
# prepended underscore
|
# prepended underscore
|
||||||
s/EXPORT\s+\|([\$\w]*)\|/.global $1 \n\t.type $1, function/;
|
s/EXPORT\s+\|([\$\w]*)\|/.global $1 \n\t.type $1, function/;
|
||||||
|
|||||||
@@ -18,6 +18,12 @@
|
|||||||
# Usage: cat inputfile | perl ads2gas_apple.pl > outputfile
|
# Usage: cat inputfile | perl ads2gas_apple.pl > outputfile
|
||||||
#
|
#
|
||||||
|
|
||||||
|
my $chromium = 0;
|
||||||
|
|
||||||
|
foreach my $arg (@ARGV) {
|
||||||
|
$chromium = 1 if ($arg eq "-chromium");
|
||||||
|
}
|
||||||
|
|
||||||
print "@ This file was created from a .asm file\n";
|
print "@ This file was created from a .asm file\n";
|
||||||
print "@ using the ads2gas_apple.pl script.\n\n";
|
print "@ using the ads2gas_apple.pl script.\n\n";
|
||||||
print "\t.set WIDE_REFERENCE, 0\n";
|
print "\t.set WIDE_REFERENCE, 0\n";
|
||||||
@@ -120,6 +126,18 @@ while (<STDIN>)
|
|||||||
s/DCD(.*)/.long $1/;
|
s/DCD(.*)/.long $1/;
|
||||||
s/DCB(.*)/.byte $1/;
|
s/DCB(.*)/.byte $1/;
|
||||||
|
|
||||||
|
# Build a hash of all the register - alias pairs.
|
||||||
|
if (s/(.*)RN(.*)/$1 .req $2/g)
|
||||||
|
{
|
||||||
|
$register_aliases{trim($1)} = trim($2);
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (($key, $value) = each(%register_aliases))
|
||||||
|
{
|
||||||
|
s/\b$key\b/$value/g;
|
||||||
|
}
|
||||||
|
|
||||||
# Make function visible to linker, and make additional symbol with
|
# Make function visible to linker, and make additional symbol with
|
||||||
# prepended underscore
|
# prepended underscore
|
||||||
s/EXPORT\s+\|([\$\w]*)\|/.globl _$1\n\t.globl $1/;
|
s/EXPORT\s+\|([\$\w]*)\|/.globl _$1\n\t.globl $1/;
|
||||||
@@ -200,5 +218,18 @@ while (<STDIN>)
|
|||||||
s/\bMEND\b/.endm/; # No need to tell it where to stop assembling
|
s/\bMEND\b/.endm/; # No need to tell it where to stop assembling
|
||||||
next if /^\s*END\s*$/;
|
next if /^\s*END\s*$/;
|
||||||
|
|
||||||
|
# Clang used by Chromium differs slightly from clang in XCode in what it
|
||||||
|
# will accept in the assembly.
|
||||||
|
if ($chromium) {
|
||||||
|
s/qsubaddx/qsax/i;
|
||||||
|
s/qaddsubx/qasx/i;
|
||||||
|
s/ldrneb/ldrbne/i;
|
||||||
|
s/ldrneh/ldrhne/i;
|
||||||
|
s/(vqshrun\.s16 .*, \#)0$/${1}8/i;
|
||||||
|
|
||||||
|
# http://llvm.org/bugs/show_bug.cgi?id=16022
|
||||||
|
s/\.include/#include/;
|
||||||
|
}
|
||||||
|
|
||||||
print;
|
print;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -206,14 +206,14 @@ enable_codec(){
|
|||||||
enabled "${1}" || echo " enabling ${1}"
|
enabled "${1}" || echo " enabling ${1}"
|
||||||
enable_feature "${1}"
|
enable_feature "${1}"
|
||||||
|
|
||||||
is_in "${1}" vp8 vp9 && enable_feature "${1}_encoder" "${1}_decoder"
|
is_in "${1}" vp8 vp9 vp10 && enable_feature "${1}_encoder" "${1}_decoder"
|
||||||
}
|
}
|
||||||
|
|
||||||
disable_codec(){
|
disable_codec(){
|
||||||
disabled "${1}" || echo " disabling ${1}"
|
disabled "${1}" || echo " disabling ${1}"
|
||||||
disable_feature "${1}"
|
disable_feature "${1}"
|
||||||
|
|
||||||
is_in "${1}" vp8 vp9 && disable_feature "${1}_encoder" "${1}_decoder"
|
is_in "${1}" vp8 vp9 vp10 && disable_feature "${1}_encoder" "${1}_decoder"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Iterates through positional parameters, checks to confirm the parameter has
|
# Iterates through positional parameters, checks to confirm the parameter has
|
||||||
@@ -403,23 +403,6 @@ check_gcc_machine_option() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# tests for -m$2, -m$3, -m$4... toggling the feature given in $1.
|
|
||||||
check_gcc_machine_options() {
|
|
||||||
feature="$1"
|
|
||||||
shift
|
|
||||||
flags="-m$1"
|
|
||||||
shift
|
|
||||||
for opt in $*; do
|
|
||||||
flags="$flags -m$opt"
|
|
||||||
done
|
|
||||||
|
|
||||||
if enabled gcc && ! disabled "$feature" && ! check_cflags $flags; then
|
|
||||||
RTCD_OPTIONS="${RTCD_OPTIONS}--disable-$feature "
|
|
||||||
else
|
|
||||||
soft_enable "$feature"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
write_common_config_banner() {
|
write_common_config_banner() {
|
||||||
print_webm_license config.mk "##" ""
|
print_webm_license config.mk "##" ""
|
||||||
echo '# This file automatically generated by configure. Do not edit!' >> config.mk
|
echo '# This file automatically generated by configure. Do not edit!' >> config.mk
|
||||||
@@ -652,7 +635,7 @@ setup_gnu_toolchain() {
|
|||||||
AS=${AS:-${CROSS}as}
|
AS=${AS:-${CROSS}as}
|
||||||
STRIP=${STRIP:-${CROSS}strip}
|
STRIP=${STRIP:-${CROSS}strip}
|
||||||
NM=${NM:-${CROSS}nm}
|
NM=${NM:-${CROSS}nm}
|
||||||
AS_SFX=.S
|
AS_SFX=.s
|
||||||
EXE_SFX=
|
EXE_SFX=
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -691,11 +674,15 @@ check_xcode_minimum_version() {
|
|||||||
process_common_toolchain() {
|
process_common_toolchain() {
|
||||||
if [ -z "$toolchain" ]; then
|
if [ -z "$toolchain" ]; then
|
||||||
gcctarget="${CHOST:-$(gcc -dumpmachine 2> /dev/null)}"
|
gcctarget="${CHOST:-$(gcc -dumpmachine 2> /dev/null)}"
|
||||||
|
|
||||||
# detect tgt_isa
|
# detect tgt_isa
|
||||||
case "$gcctarget" in
|
case "$gcctarget" in
|
||||||
aarch64*)
|
aarch64*)
|
||||||
tgt_isa=arm64
|
tgt_isa=arm64
|
||||||
;;
|
;;
|
||||||
|
armv6*)
|
||||||
|
tgt_isa=armv6
|
||||||
|
;;
|
||||||
armv7*-hardfloat* | armv7*-gnueabihf | arm-*-gnueabihf)
|
armv7*-hardfloat* | armv7*-gnueabihf | arm-*-gnueabihf)
|
||||||
tgt_isa=armv7
|
tgt_isa=armv7
|
||||||
float_abi=hard
|
float_abi=hard
|
||||||
@@ -713,18 +700,6 @@ process_common_toolchain() {
|
|||||||
*sparc*)
|
*sparc*)
|
||||||
tgt_isa=sparc
|
tgt_isa=sparc
|
||||||
;;
|
;;
|
||||||
power*64*-*)
|
|
||||||
tgt_isa=ppc64
|
|
||||||
;;
|
|
||||||
power*)
|
|
||||||
tgt_isa=ppc
|
|
||||||
;;
|
|
||||||
*mips64el*)
|
|
||||||
tgt_isa=mips64
|
|
||||||
;;
|
|
||||||
*mips32el*)
|
|
||||||
tgt_isa=mips32
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# detect tgt_os
|
# detect tgt_os
|
||||||
@@ -753,16 +728,9 @@ process_common_toolchain() {
|
|||||||
tgt_isa=x86_64
|
tgt_isa=x86_64
|
||||||
tgt_os=darwin15
|
tgt_os=darwin15
|
||||||
;;
|
;;
|
||||||
*darwin16*)
|
|
||||||
tgt_isa=x86_64
|
|
||||||
tgt_os=darwin16
|
|
||||||
;;
|
|
||||||
x86_64*mingw32*)
|
x86_64*mingw32*)
|
||||||
tgt_os=win64
|
tgt_os=win64
|
||||||
;;
|
;;
|
||||||
x86_64*cygwin*)
|
|
||||||
tgt_os=win64
|
|
||||||
;;
|
|
||||||
*mingw32*|*cygwin*)
|
*mingw32*|*cygwin*)
|
||||||
[ -z "$tgt_isa" ] && tgt_isa=x86
|
[ -z "$tgt_isa" ] && tgt_isa=x86
|
||||||
tgt_os=win32
|
tgt_os=win32
|
||||||
@@ -810,9 +778,6 @@ process_common_toolchain() {
|
|||||||
mips*)
|
mips*)
|
||||||
enable_feature mips
|
enable_feature mips
|
||||||
;;
|
;;
|
||||||
ppc*)
|
|
||||||
enable_feature ppc
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# PIC is probably what we want when building shared libs
|
# PIC is probably what we want when building shared libs
|
||||||
@@ -881,10 +846,6 @@ process_common_toolchain() {
|
|||||||
add_cflags "-mmacosx-version-min=10.11"
|
add_cflags "-mmacosx-version-min=10.11"
|
||||||
add_ldflags "-mmacosx-version-min=10.11"
|
add_ldflags "-mmacosx-version-min=10.11"
|
||||||
;;
|
;;
|
||||||
*-darwin16-*)
|
|
||||||
add_cflags "-mmacosx-version-min=10.12"
|
|
||||||
add_ldflags "-mmacosx-version-min=10.12"
|
|
||||||
;;
|
|
||||||
*-iphonesimulator-*)
|
*-iphonesimulator-*)
|
||||||
add_cflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
|
add_cflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
|
||||||
add_ldflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
|
add_ldflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
|
||||||
@@ -922,6 +883,36 @@ process_common_toolchain() {
|
|||||||
if disabled neon && enabled neon_asm; then
|
if disabled neon && enabled neon_asm; then
|
||||||
die "Disabling neon while keeping neon-asm is not supported"
|
die "Disabling neon while keeping neon-asm is not supported"
|
||||||
fi
|
fi
|
||||||
|
case ${toolchain} in
|
||||||
|
# Apple iOS SDKs no longer support armv6 as of the version 9
|
||||||
|
# release (coincides with release of Xcode 7). Only enable media
|
||||||
|
# when using earlier SDK releases.
|
||||||
|
*-darwin*)
|
||||||
|
if [ "$(show_darwin_sdk_major_version iphoneos)" -lt 9 ]; then
|
||||||
|
soft_enable media
|
||||||
|
else
|
||||||
|
soft_disable media
|
||||||
|
RTCD_OPTIONS="${RTCD_OPTIONS}--disable-media "
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
soft_enable media
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
armv6)
|
||||||
|
case ${toolchain} in
|
||||||
|
*-darwin*)
|
||||||
|
if [ "$(show_darwin_sdk_major_version iphoneos)" -lt 9 ]; then
|
||||||
|
soft_enable media
|
||||||
|
else
|
||||||
|
die "Your iOS SDK does not support armv6."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
soft_enable media
|
||||||
|
;;
|
||||||
|
esac
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -968,7 +959,7 @@ EOF
|
|||||||
;;
|
;;
|
||||||
vs*)
|
vs*)
|
||||||
asm_conversion_cmd="${source_path}/build/make/ads2armasm_ms.pl"
|
asm_conversion_cmd="${source_path}/build/make/ads2armasm_ms.pl"
|
||||||
AS_SFX=.S
|
AS_SFX=.s
|
||||||
msvs_arch_dir=arm-msvs
|
msvs_arch_dir=arm-msvs
|
||||||
disable_feature multithread
|
disable_feature multithread
|
||||||
disable_feature unit_tests
|
disable_feature unit_tests
|
||||||
@@ -978,7 +969,6 @@ EOF
|
|||||||
# only "AppContainerApplication" which requires an AppxManifest.
|
# only "AppContainerApplication" which requires an AppxManifest.
|
||||||
# Therefore disable the examples, just build the library.
|
# Therefore disable the examples, just build the library.
|
||||||
disable_feature examples
|
disable_feature examples
|
||||||
disable_feature tools
|
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
rvct)
|
rvct)
|
||||||
@@ -1021,7 +1011,10 @@ EOF
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
android*)
|
android*)
|
||||||
if [ -n "${sdk_path}" ]; then
|
if [ -z "${sdk_path}" ]; then
|
||||||
|
die "Must specify --sdk-path for Android builds."
|
||||||
|
fi
|
||||||
|
|
||||||
SDK_PATH=${sdk_path}
|
SDK_PATH=${sdk_path}
|
||||||
COMPILER_LOCATION=`find "${SDK_PATH}" \
|
COMPILER_LOCATION=`find "${SDK_PATH}" \
|
||||||
-name "arm-linux-androideabi-gcc*" -print -quit`
|
-name "arm-linux-androideabi-gcc*" -print -quit`
|
||||||
@@ -1060,12 +1053,6 @@ EOF
|
|||||||
if enabled runtime_cpu_detect; then
|
if enabled runtime_cpu_detect; then
|
||||||
add_cflags "-I${SDK_PATH}/sources/android/cpufeatures"
|
add_cflags "-I${SDK_PATH}/sources/android/cpufeatures"
|
||||||
fi
|
fi
|
||||||
else
|
|
||||||
echo "Assuming standalone build with NDK toolchain."
|
|
||||||
echo "See build/make/Android.mk for details."
|
|
||||||
check_add_ldflags -static
|
|
||||||
soft_enable unit_tests
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
darwin*)
|
darwin*)
|
||||||
@@ -1077,7 +1064,7 @@ EOF
|
|||||||
STRIP="$(${XCRUN_FIND} strip)"
|
STRIP="$(${XCRUN_FIND} strip)"
|
||||||
NM="$(${XCRUN_FIND} nm)"
|
NM="$(${XCRUN_FIND} nm)"
|
||||||
RANLIB="$(${XCRUN_FIND} ranlib)"
|
RANLIB="$(${XCRUN_FIND} ranlib)"
|
||||||
AS_SFX=.S
|
AS_SFX=.s
|
||||||
LD="${CXX:-$(${XCRUN_FIND} ld)}"
|
LD="${CXX:-$(${XCRUN_FIND} ld)}"
|
||||||
|
|
||||||
# ASFLAGS is written here instead of using check_add_asflags
|
# ASFLAGS is written here instead of using check_add_asflags
|
||||||
@@ -1186,20 +1173,10 @@ EOF
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if enabled mmi; then
|
|
||||||
tgt_isa=loongson3a
|
|
||||||
check_add_ldflags -march=loongson3a
|
|
||||||
fi
|
|
||||||
|
|
||||||
check_add_cflags -march=${tgt_isa}
|
check_add_cflags -march=${tgt_isa}
|
||||||
check_add_asflags -march=${tgt_isa}
|
check_add_asflags -march=${tgt_isa}
|
||||||
check_add_asflags -KPIC
|
check_add_asflags -KPIC
|
||||||
;;
|
;;
|
||||||
ppc*)
|
|
||||||
link_with_cc=gcc
|
|
||||||
setup_gnu_toolchain
|
|
||||||
check_gcc_machine_option "vsx"
|
|
||||||
;;
|
|
||||||
x86*)
|
x86*)
|
||||||
case ${tgt_os} in
|
case ${tgt_os} in
|
||||||
win*)
|
win*)
|
||||||
@@ -1254,13 +1231,6 @@ EOF
|
|||||||
AS=msvs
|
AS=msvs
|
||||||
msvs_arch_dir=x86-msvs
|
msvs_arch_dir=x86-msvs
|
||||||
vc_version=${tgt_cc##vs}
|
vc_version=${tgt_cc##vs}
|
||||||
case $vc_version in
|
|
||||||
7|8|9|10|11|12|13|14)
|
|
||||||
echo "${tgt_cc} does not support avx512, disabling....."
|
|
||||||
RTCD_OPTIONS="${RTCD_OPTIONS}--disable-avx512 "
|
|
||||||
soft_disable avx512
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
case $vc_version in
|
case $vc_version in
|
||||||
7|8|9|10)
|
7|8|9|10)
|
||||||
echo "${tgt_cc} does not support avx/avx2, disabling....."
|
echo "${tgt_cc} does not support avx/avx2, disabling....."
|
||||||
@@ -1304,19 +1274,10 @@ EOF
|
|||||||
fi
|
fi
|
||||||
elif disabled $ext; then
|
elif disabled $ext; then
|
||||||
disable_exts="yes"
|
disable_exts="yes"
|
||||||
else
|
|
||||||
if [ "$ext" = "avx512" ]; then
|
|
||||||
check_gcc_machine_options $ext avx512f avx512cd avx512bw avx512dq avx512vl
|
|
||||||
else
|
else
|
||||||
# use the shortened version for the flag: sse4_1 -> sse4
|
# use the shortened version for the flag: sse4_1 -> sse4
|
||||||
check_gcc_machine_option ${ext%_*} $ext
|
check_gcc_machine_option ${ext%_*} $ext
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
# https://bugs.chromium.org/p/webm/issues/detail?id=1464
|
|
||||||
# The assembly optimizations for vpx_sub_pixel_variance do not link with
|
|
||||||
# gcc 6.
|
|
||||||
enabled sse2 && soft_enable pic
|
|
||||||
done
|
done
|
||||||
|
|
||||||
if enabled external_build; then
|
if enabled external_build; then
|
||||||
@@ -1341,6 +1302,7 @@ EOF
|
|||||||
esac
|
esac
|
||||||
log_echo " using $AS"
|
log_echo " using $AS"
|
||||||
fi
|
fi
|
||||||
|
[ "${AS##*/}" = nasm ] && add_asflags -Ox
|
||||||
AS_SFX=.asm
|
AS_SFX=.asm
|
||||||
case ${tgt_os} in
|
case ${tgt_os} in
|
||||||
win32)
|
win32)
|
||||||
@@ -1349,7 +1311,7 @@ EOF
|
|||||||
EXE_SFX=.exe
|
EXE_SFX=.exe
|
||||||
;;
|
;;
|
||||||
win64)
|
win64)
|
||||||
add_asflags -f win64
|
add_asflags -f x64
|
||||||
enabled debug && add_asflags -g cv8
|
enabled debug && add_asflags -g cv8
|
||||||
EXE_SFX=.exe
|
EXE_SFX=.exe
|
||||||
;;
|
;;
|
||||||
@@ -1463,7 +1425,6 @@ EOF
|
|||||||
*-win*-vs*)
|
*-win*-vs*)
|
||||||
;;
|
;;
|
||||||
*-android-gcc)
|
*-android-gcc)
|
||||||
# bionic includes basic pthread functionality, obviating -lpthread.
|
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
check_header pthread.h && add_extralibs -lpthread
|
check_header pthread.h && add_extralibs -lpthread
|
||||||
@@ -1483,10 +1444,6 @@ EOF
|
|||||||
echo "msa optimizations are available only for little endian platforms"
|
echo "msa optimizations are available only for little endian platforms"
|
||||||
disable_feature msa
|
disable_feature msa
|
||||||
fi
|
fi
|
||||||
if enabled mmi; then
|
|
||||||
echo "mmi optimizations are available only for little endian platforms"
|
|
||||||
disable_feature mmi
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ files.
|
|||||||
Options:
|
Options:
|
||||||
--help Print this message
|
--help Print this message
|
||||||
--out=outfile Redirect output to a file
|
--out=outfile Redirect output to a file
|
||||||
--ver=version Version (7,8,9,10,11,12,14,15) of visual studio to generate for
|
--ver=version Version (7,8,9,10,11,12,14) of visual studio to generate for
|
||||||
--target=isa-os-cc Target specifier
|
--target=isa-os-cc Target specifier
|
||||||
EOF
|
EOF
|
||||||
exit 1
|
exit 1
|
||||||
@@ -215,7 +215,7 @@ for opt in "$@"; do
|
|||||||
;;
|
;;
|
||||||
--ver=*) vs_ver="$optval"
|
--ver=*) vs_ver="$optval"
|
||||||
case $optval in
|
case $optval in
|
||||||
10|11|12|14|15)
|
10|11|12|14)
|
||||||
;;
|
;;
|
||||||
*) die Unrecognized Visual Studio Version in $opt
|
*) die Unrecognized Visual Studio Version in $opt
|
||||||
;;
|
;;
|
||||||
@@ -240,12 +240,9 @@ case "${vs_ver:-10}" in
|
|||||||
12) sln_vers="12.00"
|
12) sln_vers="12.00"
|
||||||
sln_vers_str="Visual Studio 2013"
|
sln_vers_str="Visual Studio 2013"
|
||||||
;;
|
;;
|
||||||
14) sln_vers="12.00"
|
14) sln_vers="14.00"
|
||||||
sln_vers_str="Visual Studio 2015"
|
sln_vers_str="Visual Studio 2015"
|
||||||
;;
|
;;
|
||||||
15) sln_vers="12.00"
|
|
||||||
sln_vers_str="Visual Studio 2017"
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
sfx=vcxproj
|
sfx=vcxproj
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ Options:
|
|||||||
--name=project_name Name of the project (required)
|
--name=project_name Name of the project (required)
|
||||||
--proj-guid=GUID GUID to use for the project
|
--proj-guid=GUID GUID to use for the project
|
||||||
--module-def=filename File containing export definitions (for DLLs)
|
--module-def=filename File containing export definitions (for DLLs)
|
||||||
--ver=version Version (10,11,12,14,15) of visual studio to generate for
|
--ver=version Version (10,11,12,14) of visual studio to generate for
|
||||||
--src-path-bare=dir Path to root of source tree
|
--src-path-bare=dir Path to root of source tree
|
||||||
-Ipath/to/include Additional include directories
|
-Ipath/to/include Additional include directories
|
||||||
-DFLAG[=value] Preprocessor macros to define
|
-DFLAG[=value] Preprocessor macros to define
|
||||||
@@ -82,7 +82,7 @@ generate_filter() {
|
|||||||
| sed -e "s,$src_path_bare,," \
|
| sed -e "s,$src_path_bare,," \
|
||||||
-e 's/^[\./]\+//g' -e 's,[:/ ],_,g')
|
-e 's/^[\./]\+//g' -e 's,[:/ ],_,g')
|
||||||
|
|
||||||
if ([ "$pat" == "asm" ] || [ "$pat" == "s" ] || [ "$pat" == "S" ]) && $asm_use_custom_step; then
|
if ([ "$pat" == "asm" ] || [ "$pat" == "s" ]) && $asm_use_custom_step; then
|
||||||
# Avoid object file name collisions, i.e. vpx_config.c and
|
# Avoid object file name collisions, i.e. vpx_config.c and
|
||||||
# vpx_config.asm produce the same object file without
|
# vpx_config.asm produce the same object file without
|
||||||
# this additional suffix.
|
# this additional suffix.
|
||||||
@@ -168,7 +168,7 @@ for opt in "$@"; do
|
|||||||
--ver=*)
|
--ver=*)
|
||||||
vs_ver="$optval"
|
vs_ver="$optval"
|
||||||
case "$optval" in
|
case "$optval" in
|
||||||
10|11|12|14|15)
|
10|11|12|14)
|
||||||
;;
|
;;
|
||||||
*) die Unrecognized Visual Studio Version in $opt
|
*) die Unrecognized Visual Studio Version in $opt
|
||||||
;;
|
;;
|
||||||
@@ -203,7 +203,7 @@ for opt in "$@"; do
|
|||||||
# The paths in file_list are fixed outside of the loop.
|
# The paths in file_list are fixed outside of the loop.
|
||||||
file_list[${#file_list[@]}]="$opt"
|
file_list[${#file_list[@]}]="$opt"
|
||||||
case "$opt" in
|
case "$opt" in
|
||||||
*.asm|*.[Ss]) uses_asm=true
|
*.asm|*.s) uses_asm=true
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
@@ -218,7 +218,7 @@ guid=${guid:-`generate_uuid`}
|
|||||||
asm_use_custom_step=false
|
asm_use_custom_step=false
|
||||||
uses_asm=${uses_asm:-false}
|
uses_asm=${uses_asm:-false}
|
||||||
case "${vs_ver:-11}" in
|
case "${vs_ver:-11}" in
|
||||||
10|11|12|14|15)
|
10|11|12|14)
|
||||||
asm_use_custom_step=$uses_asm
|
asm_use_custom_step=$uses_asm
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -347,9 +347,6 @@ generate_vcxproj() {
|
|||||||
if [ "$vs_ver" = "14" ]; then
|
if [ "$vs_ver" = "14" ]; then
|
||||||
tag_content PlatformToolset v140
|
tag_content PlatformToolset v140
|
||||||
fi
|
fi
|
||||||
if [ "$vs_ver" = "15" ]; then
|
|
||||||
tag_content PlatformToolset v141
|
|
||||||
fi
|
|
||||||
tag_content CharacterSet Unicode
|
tag_content CharacterSet Unicode
|
||||||
if [ "$config" = "Release" ]; then
|
if [ "$config" = "Release" ]; then
|
||||||
tag_content WholeProgramOptimization true
|
tag_content WholeProgramOptimization true
|
||||||
@@ -455,7 +452,7 @@ generate_vcxproj() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
open_tag ItemGroup
|
open_tag ItemGroup
|
||||||
generate_filter "Source Files" "c;cc;cpp;def;odl;idl;hpj;bat;asm;asmx;s;S"
|
generate_filter "Source Files" "c;cc;cpp;def;odl;idl;hpj;bat;asm;asmx;s"
|
||||||
close_tag ItemGroup
|
close_tag ItemGroup
|
||||||
open_tag ItemGroup
|
open_tag ItemGroup
|
||||||
generate_filter "Header Files" "h;hm;inl;inc;xsd"
|
generate_filter "Header Files" "h;hm;inl;inc;xsd"
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ ARM_TARGETS="arm64-darwin-gcc
|
|||||||
armv7s-darwin-gcc"
|
armv7s-darwin-gcc"
|
||||||
SIM_TARGETS="x86-iphonesimulator-gcc
|
SIM_TARGETS="x86-iphonesimulator-gcc
|
||||||
x86_64-iphonesimulator-gcc"
|
x86_64-iphonesimulator-gcc"
|
||||||
OSX_TARGETS="x86-darwin16-gcc
|
OSX_TARGETS="x86-darwin15-gcc
|
||||||
x86_64-darwin16-gcc"
|
x86_64-darwin15-gcc"
|
||||||
TARGETS="${ARM_TARGETS} ${SIM_TARGETS}"
|
TARGETS="${ARM_TARGETS} ${SIM_TARGETS}"
|
||||||
|
|
||||||
# Configures for the target specified by $1, and invokes make with the dist
|
# Configures for the target specified by $1, and invokes make with the dist
|
||||||
@@ -271,7 +271,7 @@ cat << EOF
|
|||||||
--help: Display this message and exit.
|
--help: Display this message and exit.
|
||||||
--enable-shared: Build a dynamic framework for use on iOS 8 or later.
|
--enable-shared: Build a dynamic framework for use on iOS 8 or later.
|
||||||
--extra-configure-args <args>: Extra args to pass when configuring libvpx.
|
--extra-configure-args <args>: Extra args to pass when configuring libvpx.
|
||||||
--macosx: Uses darwin16 targets instead of iphonesimulator targets for x86
|
--macosx: Uses darwin15 targets instead of iphonesimulator targets for x86
|
||||||
and x86_64. Allows linking to framework when builds target MacOSX
|
and x86_64. Allows linking to framework when builds target MacOSX
|
||||||
instead of iOS.
|
instead of iOS.
|
||||||
--preserve-build-output: Do not delete the build directory.
|
--preserve-build-output: Do not delete the build directory.
|
||||||
|
|||||||
@@ -1,13 +1,4 @@
|
|||||||
#!/usr/bin/env perl
|
#!/usr/bin/env perl
|
||||||
##
|
|
||||||
## Copyright (c) 2017 The WebM project authors. All Rights Reserved.
|
|
||||||
##
|
|
||||||
## Use of this source code is governed by a BSD-style license
|
|
||||||
## that can be found in the LICENSE file in the root of the source
|
|
||||||
## tree. An additional intellectual property rights grant can be found
|
|
||||||
## in the file PATENTS. All contributing project authors may
|
|
||||||
## be found in the AUTHORS file in the root of the source tree.
|
|
||||||
##
|
|
||||||
|
|
||||||
no strict 'refs';
|
no strict 'refs';
|
||||||
use warnings;
|
use warnings;
|
||||||
@@ -209,7 +200,6 @@ sub filter {
|
|||||||
sub common_top() {
|
sub common_top() {
|
||||||
my $include_guard = uc($opts{sym})."_H_";
|
my $include_guard = uc($opts{sym})."_H_";
|
||||||
print <<EOF;
|
print <<EOF;
|
||||||
// This file is generated. Do not edit.
|
|
||||||
#ifndef ${include_guard}
|
#ifndef ${include_guard}
|
||||||
#define ${include_guard}
|
#define ${include_guard}
|
||||||
|
|
||||||
@@ -330,45 +320,8 @@ EOF
|
|||||||
print <<EOF;
|
print <<EOF;
|
||||||
#if HAVE_DSPR2
|
#if HAVE_DSPR2
|
||||||
void vpx_dsputil_static_init();
|
void vpx_dsputil_static_init();
|
||||||
#if CONFIG_VP8
|
|
||||||
void dsputil_static_init();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
vpx_dsputil_static_init();
|
vpx_dsputil_static_init();
|
||||||
#if CONFIG_VP8
|
|
||||||
dsputil_static_init();
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
EOF
|
|
||||||
common_bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub ppc() {
|
|
||||||
determine_indirection("c", @ALL_ARCHS);
|
|
||||||
|
|
||||||
# Assign the helper variable for each enabled extension
|
|
||||||
foreach my $opt (@ALL_ARCHS) {
|
|
||||||
my $opt_uc = uc $opt;
|
|
||||||
eval "\$have_${opt}=\"flags & HAS_${opt_uc}\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
common_top;
|
|
||||||
print <<EOF;
|
|
||||||
#include "vpx_config.h"
|
|
||||||
|
|
||||||
#ifdef RTCD_C
|
|
||||||
#include "vpx_ports/ppc.h"
|
|
||||||
static void setup_rtcd_internal(void)
|
|
||||||
{
|
|
||||||
int flags = ppc_simd_caps();
|
|
||||||
(void)flags;
|
|
||||||
EOF
|
|
||||||
|
|
||||||
set_function_pointers("c", @ALL_ARCHS);
|
|
||||||
|
|
||||||
print <<EOF;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
EOF
|
EOF
|
||||||
@@ -401,10 +354,10 @@ EOF
|
|||||||
|
|
||||||
&require("c");
|
&require("c");
|
||||||
if ($opts{arch} eq 'x86') {
|
if ($opts{arch} eq 'x86') {
|
||||||
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2 avx512/);
|
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2/);
|
||||||
x86;
|
x86;
|
||||||
} elsif ($opts{arch} eq 'x86_64') {
|
} elsif ($opts{arch} eq 'x86_64') {
|
||||||
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2 avx512/);
|
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2/);
|
||||||
@REQUIRES = filter(keys %required ? keys %required : qw/mmx sse sse2/);
|
@REQUIRES = filter(keys %required ? keys %required : qw/mmx sse sse2/);
|
||||||
&require(@REQUIRES);
|
&require(@REQUIRES);
|
||||||
x86;
|
x86;
|
||||||
@@ -421,22 +374,20 @@ if ($opts{arch} eq 'x86') {
|
|||||||
@ALL_ARCHS = filter("$opts{arch}", qw/msa/);
|
@ALL_ARCHS = filter("$opts{arch}", qw/msa/);
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
if (/HAVE_MMI=yes/) {
|
|
||||||
@ALL_ARCHS = filter("$opts{arch}", qw/mmi/);
|
|
||||||
last;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
close CONFIG_FILE;
|
close CONFIG_FILE;
|
||||||
mips;
|
mips;
|
||||||
|
} elsif ($opts{arch} eq 'armv6') {
|
||||||
|
@ALL_ARCHS = filter(qw/media/);
|
||||||
|
arm;
|
||||||
} elsif ($opts{arch} =~ /armv7\w?/) {
|
} elsif ($opts{arch} =~ /armv7\w?/) {
|
||||||
@ALL_ARCHS = filter(qw/neon_asm neon/);
|
@ALL_ARCHS = filter(qw/media neon_asm neon/);
|
||||||
|
@REQUIRES = filter(keys %required ? keys %required : qw/media/);
|
||||||
|
&require(@REQUIRES);
|
||||||
arm;
|
arm;
|
||||||
} elsif ($opts{arch} eq 'armv8' || $opts{arch} eq 'arm64' ) {
|
} elsif ($opts{arch} eq 'armv8' || $opts{arch} eq 'arm64' ) {
|
||||||
@ALL_ARCHS = filter(qw/neon/);
|
@ALL_ARCHS = filter(qw/neon/);
|
||||||
arm;
|
arm;
|
||||||
} elsif ($opts{arch} =~ /^ppc/ ) {
|
|
||||||
@ALL_ARCHS = filter(qw/vsx/);
|
|
||||||
ppc;
|
|
||||||
} else {
|
} else {
|
||||||
unoptimized;
|
unoptimized;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ if [ ${bare} ]; then
|
|||||||
echo "${changelog_version}${git_version_id}" > $$.tmp
|
echo "${changelog_version}${git_version_id}" > $$.tmp
|
||||||
else
|
else
|
||||||
cat<<EOF>$$.tmp
|
cat<<EOF>$$.tmp
|
||||||
// This file is generated. Do not edit.
|
|
||||||
#define VERSION_MAJOR $major_version
|
#define VERSION_MAJOR $major_version
|
||||||
#define VERSION_MINOR $minor_version
|
#define VERSION_MINOR $minor_version
|
||||||
#define VERSION_PATCH $patch_version
|
#define VERSION_PATCH $patch_version
|
||||||
|
|||||||
@@ -2,4 +2,3 @@
|
|||||||
GERRIT_HOST: chromium-review.googlesource.com
|
GERRIT_HOST: chromium-review.googlesource.com
|
||||||
GERRIT_PORT: 29418
|
GERRIT_PORT: 29418
|
||||||
CODE_REVIEW_SERVER: chromium-review.googlesource.com
|
CODE_REVIEW_SERVER: chromium-review.googlesource.com
|
||||||
GERRIT_SQUASH_UPLOADS: False
|
|
||||||
|
|||||||
107
configure
vendored
107
configure
vendored
@@ -22,7 +22,6 @@ show_help(){
|
|||||||
Advanced options:
|
Advanced options:
|
||||||
${toggle_libs} libraries
|
${toggle_libs} libraries
|
||||||
${toggle_examples} examples
|
${toggle_examples} examples
|
||||||
${toggle_tools} tools
|
|
||||||
${toggle_docs} documentation
|
${toggle_docs} documentation
|
||||||
${toggle_unit_tests} unit tests
|
${toggle_unit_tests} unit tests
|
||||||
${toggle_decode_perf_tests} build decoder perf tests with unit tests
|
${toggle_decode_perf_tests} build decoder perf tests with unit tests
|
||||||
@@ -35,12 +34,11 @@ Advanced options:
|
|||||||
${toggle_codec_srcs} in/exclude codec library source code
|
${toggle_codec_srcs} in/exclude codec library source code
|
||||||
${toggle_debug_libs} in/exclude debug version of libraries
|
${toggle_debug_libs} in/exclude debug version of libraries
|
||||||
${toggle_static_msvcrt} use static MSVCRT (VS builds only)
|
${toggle_static_msvcrt} use static MSVCRT (VS builds only)
|
||||||
${toggle_vp9_highbitdepth} use VP9 high bit depth (10/12) profiles
|
${toggle_vpx_highbitdepth} use VPX high bit depth (10/12) profiles
|
||||||
${toggle_better_hw_compatibility}
|
${toggle_better_hw_compatibility}
|
||||||
enable encoder to produce streams with better
|
enable encoder to produce streams with better
|
||||||
hardware decoder compatibility
|
hardware decoder compatibility
|
||||||
${toggle_vp8} VP8 codec support
|
${toggle_vp10} VP10 codec support
|
||||||
${toggle_vp9} VP9 codec support
|
|
||||||
${toggle_internal_stats} output of encoder internal stats for debug, if supported (encoders)
|
${toggle_internal_stats} output of encoder internal stats for debug, if supported (encoders)
|
||||||
${toggle_postproc} postprocessing
|
${toggle_postproc} postprocessing
|
||||||
${toggle_vp9_postproc} vp9 specific postprocessing
|
${toggle_vp9_postproc} vp9 specific postprocessing
|
||||||
@@ -98,9 +96,11 @@ EOF
|
|||||||
|
|
||||||
# all_platforms is a list of all supported target platforms. Maintain
|
# all_platforms is a list of all supported target platforms. Maintain
|
||||||
# alphabetically by architecture, generic-gnu last.
|
# alphabetically by architecture, generic-gnu last.
|
||||||
all_platforms="${all_platforms} arm64-android-gcc"
|
|
||||||
all_platforms="${all_platforms} arm64-darwin-gcc"
|
all_platforms="${all_platforms} arm64-darwin-gcc"
|
||||||
all_platforms="${all_platforms} arm64-linux-gcc"
|
all_platforms="${all_platforms} arm64-linux-gcc"
|
||||||
|
all_platforms="${all_platforms} armv6-linux-rvct"
|
||||||
|
all_platforms="${all_platforms} armv6-linux-gcc"
|
||||||
|
all_platforms="${all_platforms} armv6-none-rvct"
|
||||||
all_platforms="${all_platforms} armv7-android-gcc" #neon Cortex-A8
|
all_platforms="${all_platforms} armv7-android-gcc" #neon Cortex-A8
|
||||||
all_platforms="${all_platforms} armv7-darwin-gcc" #neon Cortex-A8
|
all_platforms="${all_platforms} armv7-darwin-gcc" #neon Cortex-A8
|
||||||
all_platforms="${all_platforms} armv7-linux-rvct" #neon Cortex-A8
|
all_platforms="${all_platforms} armv7-linux-rvct" #neon Cortex-A8
|
||||||
@@ -109,13 +109,10 @@ all_platforms="${all_platforms} armv7-none-rvct" #neon Cortex-A8
|
|||||||
all_platforms="${all_platforms} armv7-win32-vs11"
|
all_platforms="${all_platforms} armv7-win32-vs11"
|
||||||
all_platforms="${all_platforms} armv7-win32-vs12"
|
all_platforms="${all_platforms} armv7-win32-vs12"
|
||||||
all_platforms="${all_platforms} armv7-win32-vs14"
|
all_platforms="${all_platforms} armv7-win32-vs14"
|
||||||
all_platforms="${all_platforms} armv7-win32-vs15"
|
|
||||||
all_platforms="${all_platforms} armv7s-darwin-gcc"
|
all_platforms="${all_platforms} armv7s-darwin-gcc"
|
||||||
all_platforms="${all_platforms} armv8-linux-gcc"
|
all_platforms="${all_platforms} armv8-linux-gcc"
|
||||||
all_platforms="${all_platforms} mips32-linux-gcc"
|
all_platforms="${all_platforms} mips32-linux-gcc"
|
||||||
all_platforms="${all_platforms} mips64-linux-gcc"
|
all_platforms="${all_platforms} mips64-linux-gcc"
|
||||||
all_platforms="${all_platforms} ppc64-linux-gcc"
|
|
||||||
all_platforms="${all_platforms} ppc64le-linux-gcc"
|
|
||||||
all_platforms="${all_platforms} sparc-solaris-gcc"
|
all_platforms="${all_platforms} sparc-solaris-gcc"
|
||||||
all_platforms="${all_platforms} x86-android-gcc"
|
all_platforms="${all_platforms} x86-android-gcc"
|
||||||
all_platforms="${all_platforms} x86-darwin8-gcc"
|
all_platforms="${all_platforms} x86-darwin8-gcc"
|
||||||
@@ -128,7 +125,6 @@ all_platforms="${all_platforms} x86-darwin12-gcc"
|
|||||||
all_platforms="${all_platforms} x86-darwin13-gcc"
|
all_platforms="${all_platforms} x86-darwin13-gcc"
|
||||||
all_platforms="${all_platforms} x86-darwin14-gcc"
|
all_platforms="${all_platforms} x86-darwin14-gcc"
|
||||||
all_platforms="${all_platforms} x86-darwin15-gcc"
|
all_platforms="${all_platforms} x86-darwin15-gcc"
|
||||||
all_platforms="${all_platforms} x86-darwin16-gcc"
|
|
||||||
all_platforms="${all_platforms} x86-iphonesimulator-gcc"
|
all_platforms="${all_platforms} x86-iphonesimulator-gcc"
|
||||||
all_platforms="${all_platforms} x86-linux-gcc"
|
all_platforms="${all_platforms} x86-linux-gcc"
|
||||||
all_platforms="${all_platforms} x86-linux-icc"
|
all_platforms="${all_platforms} x86-linux-icc"
|
||||||
@@ -139,7 +135,6 @@ all_platforms="${all_platforms} x86-win32-vs10"
|
|||||||
all_platforms="${all_platforms} x86-win32-vs11"
|
all_platforms="${all_platforms} x86-win32-vs11"
|
||||||
all_platforms="${all_platforms} x86-win32-vs12"
|
all_platforms="${all_platforms} x86-win32-vs12"
|
||||||
all_platforms="${all_platforms} x86-win32-vs14"
|
all_platforms="${all_platforms} x86-win32-vs14"
|
||||||
all_platforms="${all_platforms} x86-win32-vs15"
|
|
||||||
all_platforms="${all_platforms} x86_64-android-gcc"
|
all_platforms="${all_platforms} x86_64-android-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-darwin9-gcc"
|
all_platforms="${all_platforms} x86_64-darwin9-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-darwin10-gcc"
|
all_platforms="${all_platforms} x86_64-darwin10-gcc"
|
||||||
@@ -148,7 +143,6 @@ all_platforms="${all_platforms} x86_64-darwin12-gcc"
|
|||||||
all_platforms="${all_platforms} x86_64-darwin13-gcc"
|
all_platforms="${all_platforms} x86_64-darwin13-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-darwin14-gcc"
|
all_platforms="${all_platforms} x86_64-darwin14-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-darwin15-gcc"
|
all_platforms="${all_platforms} x86_64-darwin15-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-darwin16-gcc"
|
|
||||||
all_platforms="${all_platforms} x86_64-iphonesimulator-gcc"
|
all_platforms="${all_platforms} x86_64-iphonesimulator-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-linux-gcc"
|
all_platforms="${all_platforms} x86_64-linux-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-linux-icc"
|
all_platforms="${all_platforms} x86_64-linux-icc"
|
||||||
@@ -158,26 +152,22 @@ all_platforms="${all_platforms} x86_64-win64-vs10"
|
|||||||
all_platforms="${all_platforms} x86_64-win64-vs11"
|
all_platforms="${all_platforms} x86_64-win64-vs11"
|
||||||
all_platforms="${all_platforms} x86_64-win64-vs12"
|
all_platforms="${all_platforms} x86_64-win64-vs12"
|
||||||
all_platforms="${all_platforms} x86_64-win64-vs14"
|
all_platforms="${all_platforms} x86_64-win64-vs14"
|
||||||
all_platforms="${all_platforms} x86_64-win64-vs15"
|
|
||||||
all_platforms="${all_platforms} generic-gnu"
|
all_platforms="${all_platforms} generic-gnu"
|
||||||
|
|
||||||
# all_targets is a list of all targets that can be configured
|
# all_targets is a list of all targets that can be configured
|
||||||
# note that these should be in dependency order for now.
|
# note that these should be in dependency order for now.
|
||||||
all_targets="libs examples tools docs"
|
all_targets="libs examples docs"
|
||||||
|
|
||||||
# all targets available are enabled, by default.
|
# all targets available are enabled, by default.
|
||||||
for t in ${all_targets}; do
|
for t in ${all_targets}; do
|
||||||
[ -f "${source_path}/${t}.mk" ] && enable_feature ${t}
|
[ -f "${source_path}/${t}.mk" ] && enable_feature ${t}
|
||||||
done
|
done
|
||||||
|
|
||||||
if ! diff --version >/dev/null; then
|
|
||||||
die "diff missing: Try installing diffutils via your package manager."
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! perl --version >/dev/null; then
|
if ! perl --version >/dev/null; then
|
||||||
die "Perl is required to build"
|
die "Perl is required to build"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [ "`cd \"${source_path}\" && pwd`" != "`pwd`" ]; then
|
if [ "`cd \"${source_path}\" && pwd`" != "`pwd`" ]; then
|
||||||
# test to see if source_path already configured
|
# test to see if source_path already configured
|
||||||
if [ -f "${source_path}/vpx_config.h" ]; then
|
if [ -f "${source_path}/vpx_config.h" ]; then
|
||||||
@@ -199,8 +189,7 @@ if [ ${doxy_major:-0} -ge 1 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# disable codecs when their source directory does not exist
|
# disable codecs when their source directory does not exist
|
||||||
[ -d "${source_path}/vp8" ] || disable_codec vp8
|
[ -d "${source_path}/vp10" ] || disable_codec vp10
|
||||||
[ -d "${source_path}/vp9" ] || disable_codec vp9
|
|
||||||
|
|
||||||
# install everything except the sources, by default. sources will have
|
# install everything except the sources, by default. sources will have
|
||||||
# to be enabled when doing dist builds, since that's no longer a common
|
# to be enabled when doing dist builds, since that's no longer a common
|
||||||
@@ -218,14 +207,11 @@ enable_feature os_support
|
|||||||
enable_feature temporal_denoising
|
enable_feature temporal_denoising
|
||||||
|
|
||||||
CODECS="
|
CODECS="
|
||||||
vp8_encoder
|
vp10_encoder
|
||||||
vp8_decoder
|
vp10_decoder
|
||||||
vp9_encoder
|
|
||||||
vp9_decoder
|
|
||||||
"
|
"
|
||||||
CODEC_FAMILIES="
|
CODEC_FAMILIES="
|
||||||
vp8
|
vp10
|
||||||
vp9
|
|
||||||
"
|
"
|
||||||
|
|
||||||
ARCH_LIST="
|
ARCH_LIST="
|
||||||
@@ -233,7 +219,6 @@ ARCH_LIST="
|
|||||||
mips
|
mips
|
||||||
x86
|
x86
|
||||||
x86_64
|
x86_64
|
||||||
ppc
|
|
||||||
"
|
"
|
||||||
ARCH_EXT_LIST_X86="
|
ARCH_EXT_LIST_X86="
|
||||||
mmx
|
mmx
|
||||||
@@ -244,14 +229,10 @@ ARCH_EXT_LIST_X86="
|
|||||||
sse4_1
|
sse4_1
|
||||||
avx
|
avx
|
||||||
avx2
|
avx2
|
||||||
avx512
|
|
||||||
"
|
"
|
||||||
|
|
||||||
ARCH_EXT_LIST_LOONGSON="
|
|
||||||
mmi
|
|
||||||
"
|
|
||||||
|
|
||||||
ARCH_EXT_LIST="
|
ARCH_EXT_LIST="
|
||||||
|
edsp
|
||||||
|
media
|
||||||
neon
|
neon
|
||||||
neon_asm
|
neon_asm
|
||||||
|
|
||||||
@@ -261,10 +242,6 @@ ARCH_EXT_LIST="
|
|||||||
mips64
|
mips64
|
||||||
|
|
||||||
${ARCH_EXT_LIST_X86}
|
${ARCH_EXT_LIST_X86}
|
||||||
|
|
||||||
vsx
|
|
||||||
|
|
||||||
${ARCH_EXT_LIST_LOONGSON}
|
|
||||||
"
|
"
|
||||||
HAVE_LIST="
|
HAVE_LIST="
|
||||||
${ARCH_EXT_LIST}
|
${ARCH_EXT_LIST}
|
||||||
@@ -276,6 +253,27 @@ EXPERIMENT_LIST="
|
|||||||
spatial_svc
|
spatial_svc
|
||||||
fp_mb_stats
|
fp_mb_stats
|
||||||
emulate_hardware
|
emulate_hardware
|
||||||
|
var_tx
|
||||||
|
rect_tx
|
||||||
|
ref_mv
|
||||||
|
dual_filter
|
||||||
|
ext_tx
|
||||||
|
ext_intra
|
||||||
|
ext_inter
|
||||||
|
ext_interp
|
||||||
|
ext_refs
|
||||||
|
global_motion
|
||||||
|
new_quant
|
||||||
|
supertx
|
||||||
|
ans
|
||||||
|
loop_restoration
|
||||||
|
ext_partition
|
||||||
|
ext_partition_types
|
||||||
|
ext_tile
|
||||||
|
obmc
|
||||||
|
warped_motion
|
||||||
|
entropy
|
||||||
|
bidir_pred
|
||||||
"
|
"
|
||||||
CONFIG_LIST="
|
CONFIG_LIST="
|
||||||
dependency_tracking
|
dependency_tracking
|
||||||
@@ -326,11 +324,10 @@ CONFIG_LIST="
|
|||||||
temporal_denoising
|
temporal_denoising
|
||||||
vp9_temporal_denoising
|
vp9_temporal_denoising
|
||||||
coefficient_range_checking
|
coefficient_range_checking
|
||||||
vp9_highbitdepth
|
vpx_highbitdepth
|
||||||
better_hw_compatibility
|
better_hw_compatibility
|
||||||
experimental
|
experimental
|
||||||
size_limit
|
size_limit
|
||||||
always_adjust_bpm
|
|
||||||
${EXPERIMENT_LIST}
|
${EXPERIMENT_LIST}
|
||||||
"
|
"
|
||||||
CMDLINE_SELECT="
|
CMDLINE_SELECT="
|
||||||
@@ -353,7 +350,6 @@ CMDLINE_SELECT="
|
|||||||
|
|
||||||
libs
|
libs
|
||||||
examples
|
examples
|
||||||
tools
|
|
||||||
docs
|
docs
|
||||||
libc
|
libc
|
||||||
as
|
as
|
||||||
@@ -388,9 +384,8 @@ CMDLINE_SELECT="
|
|||||||
vp9_temporal_denoising
|
vp9_temporal_denoising
|
||||||
coefficient_range_checking
|
coefficient_range_checking
|
||||||
better_hw_compatibility
|
better_hw_compatibility
|
||||||
vp9_highbitdepth
|
vpx_highbitdepth
|
||||||
experimental
|
experimental
|
||||||
always_adjust_bpm
|
|
||||||
"
|
"
|
||||||
|
|
||||||
process_cmdline() {
|
process_cmdline() {
|
||||||
@@ -500,7 +495,7 @@ EOF
|
|||||||
#
|
#
|
||||||
# Write makefiles for all enabled targets
|
# Write makefiles for all enabled targets
|
||||||
#
|
#
|
||||||
for tgt in libs examples tools docs solution; do
|
for tgt in libs examples docs solution; do
|
||||||
tgt_fn="$tgt-$toolchain.mk"
|
tgt_fn="$tgt-$toolchain.mk"
|
||||||
|
|
||||||
if enabled $tgt; then
|
if enabled $tgt; then
|
||||||
@@ -591,29 +586,27 @@ process_toolchain() {
|
|||||||
check_add_cflags -Wall
|
check_add_cflags -Wall
|
||||||
check_add_cflags -Wdeclaration-after-statement
|
check_add_cflags -Wdeclaration-after-statement
|
||||||
check_add_cflags -Wdisabled-optimization
|
check_add_cflags -Wdisabled-optimization
|
||||||
check_add_cflags -Wfloat-conversion
|
|
||||||
check_add_cflags -Wparentheses-equality
|
|
||||||
check_add_cflags -Wpointer-arith
|
check_add_cflags -Wpointer-arith
|
||||||
check_add_cflags -Wtype-limits
|
check_add_cflags -Wtype-limits
|
||||||
check_add_cflags -Wcast-qual
|
check_add_cflags -Wcast-qual
|
||||||
check_add_cflags -Wvla
|
check_add_cflags -Wvla
|
||||||
check_add_cflags -Wimplicit-function-declaration
|
check_add_cflags -Wimplicit-function-declaration
|
||||||
check_add_cflags -Wuninitialized
|
check_add_cflags -Wuninitialized
|
||||||
check_add_cflags -Wunused
|
check_add_cflags -Wunused-variable
|
||||||
# -Wextra has some tricky cases. Rather than fix them all now, get the
|
case ${CC} in
|
||||||
# flag for as many files as possible and fix the remaining issues
|
*clang*)
|
||||||
# piecemeal.
|
# libvpx and/or clang have issues with aliasing:
|
||||||
# https://bugs.chromium.org/p/webm/issues/detail?id=1069
|
# https://code.google.com/p/webm/issues/detail?id=603
|
||||||
check_add_cflags -Wextra
|
# work around them until they are fixed
|
||||||
# check_add_cflags also adds to cxxflags. gtest does not do well with
|
check_add_cflags -fno-strict-aliasing
|
||||||
# -Wundef so add it explicitly to CFLAGS only.
|
;;
|
||||||
check_cflags -Wundef && add_cflags_only -Wundef
|
*) check_add_cflags -Wunused-but-set-variable ;;
|
||||||
|
esac
|
||||||
if enabled mips || [ -z "${INLINE}" ]; then
|
if enabled mips || [ -z "${INLINE}" ]; then
|
||||||
enabled extra_warnings || check_add_cflags -Wno-unused-function
|
enabled extra_warnings || check_add_cflags -Wno-unused-function
|
||||||
|
else
|
||||||
|
check_add_cflags -Wunused-function
|
||||||
fi
|
fi
|
||||||
# Avoid this warning for third_party C++ sources. Some reorganization
|
|
||||||
# would be needed to apply this only to test/*.cc.
|
|
||||||
check_cflags -Wshorten-64-to-32 && add_cflags_only -Wshorten-64-to-32
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if enabled icc; then
|
if enabled icc; then
|
||||||
@@ -665,7 +658,7 @@ process_toolchain() {
|
|||||||
gen_vcproj_cmd=${source_path}/build/make/gen_msvs_vcxproj.sh
|
gen_vcproj_cmd=${source_path}/build/make/gen_msvs_vcxproj.sh
|
||||||
enabled werror && gen_vcproj_cmd="${gen_vcproj_cmd} --enable-werror"
|
enabled werror && gen_vcproj_cmd="${gen_vcproj_cmd} --enable-werror"
|
||||||
all_targets="${all_targets} solution"
|
all_targets="${all_targets} solution"
|
||||||
INLINE="__inline"
|
INLINE="__forceinline"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|||||||
92
examples.mk
92
examples.mk
@@ -76,7 +76,6 @@ vpxdec.SRCS += tools_common.c tools_common.h
|
|||||||
vpxdec.SRCS += y4menc.c y4menc.h
|
vpxdec.SRCS += y4menc.c y4menc.h
|
||||||
ifeq ($(CONFIG_LIBYUV),yes)
|
ifeq ($(CONFIG_LIBYUV),yes)
|
||||||
vpxdec.SRCS += $(LIBYUV_SRCS)
|
vpxdec.SRCS += $(LIBYUV_SRCS)
|
||||||
$(BUILD_PFX)third_party/libyuv/%.cc.o: CXXFLAGS += -Wno-unused-parameter
|
|
||||||
endif
|
endif
|
||||||
ifeq ($(CONFIG_WEBM_IO),yes)
|
ifeq ($(CONFIG_WEBM_IO),yes)
|
||||||
vpxdec.SRCS += $(LIBWEBM_COMMON_SRCS)
|
vpxdec.SRCS += $(LIBWEBM_COMMON_SRCS)
|
||||||
@@ -109,22 +108,6 @@ ifeq ($(CONFIG_WEBM_IO),yes)
|
|||||||
endif
|
endif
|
||||||
vpxenc.GUID = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1
|
vpxenc.GUID = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1
|
||||||
vpxenc.DESCRIPTION = Full featured encoder
|
vpxenc.DESCRIPTION = Full featured encoder
|
||||||
ifeq ($(CONFIG_SPATIAL_SVC),yes)
|
|
||||||
EXAMPLES-$(CONFIG_VP9_ENCODER) += vp9_spatial_svc_encoder.c
|
|
||||||
vp9_spatial_svc_encoder.SRCS += args.c args.h
|
|
||||||
vp9_spatial_svc_encoder.SRCS += ivfenc.c ivfenc.h
|
|
||||||
vp9_spatial_svc_encoder.SRCS += tools_common.c tools_common.h
|
|
||||||
vp9_spatial_svc_encoder.SRCS += video_common.h
|
|
||||||
vp9_spatial_svc_encoder.SRCS += video_writer.h video_writer.c
|
|
||||||
vp9_spatial_svc_encoder.SRCS += vpx_ports/msvc.h
|
|
||||||
vp9_spatial_svc_encoder.SRCS += vpxstats.c vpxstats.h
|
|
||||||
vp9_spatial_svc_encoder.GUID = 4A38598D-627D-4505-9C7B-D4020C84100D
|
|
||||||
vp9_spatial_svc_encoder.DESCRIPTION = VP9 Spatial SVC Encoder
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(CONFIG_SHARED),yes)
|
|
||||||
EXAMPLES-$(CONFIG_VP9_ENCODER) += resize_util.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
EXAMPLES-$(CONFIG_ENCODERS) += vpx_temporal_svc_encoder.c
|
EXAMPLES-$(CONFIG_ENCODERS) += vpx_temporal_svc_encoder.c
|
||||||
vpx_temporal_svc_encoder.SRCS += ivfenc.c ivfenc.h
|
vpx_temporal_svc_encoder.SRCS += ivfenc.c ivfenc.h
|
||||||
@@ -144,16 +127,6 @@ simple_decoder.SRCS += vpx_ports/mem_ops.h
|
|||||||
simple_decoder.SRCS += vpx_ports/mem_ops_aligned.h
|
simple_decoder.SRCS += vpx_ports/mem_ops_aligned.h
|
||||||
simple_decoder.SRCS += vpx_ports/msvc.h
|
simple_decoder.SRCS += vpx_ports/msvc.h
|
||||||
simple_decoder.DESCRIPTION = Simplified decoder loop
|
simple_decoder.DESCRIPTION = Simplified decoder loop
|
||||||
EXAMPLES-$(CONFIG_DECODERS) += postproc.c
|
|
||||||
postproc.SRCS += ivfdec.h ivfdec.c
|
|
||||||
postproc.SRCS += tools_common.h tools_common.c
|
|
||||||
postproc.SRCS += video_common.h
|
|
||||||
postproc.SRCS += video_reader.h video_reader.c
|
|
||||||
postproc.SRCS += vpx_ports/mem_ops.h
|
|
||||||
postproc.SRCS += vpx_ports/mem_ops_aligned.h
|
|
||||||
postproc.SRCS += vpx_ports/msvc.h
|
|
||||||
postproc.GUID = 65E33355-F35E-4088-884D-3FD4905881D7
|
|
||||||
postproc.DESCRIPTION = Decoder postprocessor control
|
|
||||||
EXAMPLES-$(CONFIG_DECODERS) += decode_to_md5.c
|
EXAMPLES-$(CONFIG_DECODERS) += decode_to_md5.c
|
||||||
decode_to_md5.SRCS += md5_utils.h md5_utils.c
|
decode_to_md5.SRCS += md5_utils.h md5_utils.c
|
||||||
decode_to_md5.SRCS += ivfdec.h ivfdec.c
|
decode_to_md5.SRCS += ivfdec.h ivfdec.c
|
||||||
@@ -173,14 +146,14 @@ simple_encoder.SRCS += video_writer.h video_writer.c
|
|||||||
simple_encoder.SRCS += vpx_ports/msvc.h
|
simple_encoder.SRCS += vpx_ports/msvc.h
|
||||||
simple_encoder.GUID = 4607D299-8A71-4D2C-9B1D-071899B6FBFD
|
simple_encoder.GUID = 4607D299-8A71-4D2C-9B1D-071899B6FBFD
|
||||||
simple_encoder.DESCRIPTION = Simplified encoder loop
|
simple_encoder.DESCRIPTION = Simplified encoder loop
|
||||||
EXAMPLES-$(CONFIG_VP9_ENCODER) += vp9_lossless_encoder.c
|
EXAMPLES-$(CONFIG_VP10_ENCODER) += lossless_encoder.c
|
||||||
vp9_lossless_encoder.SRCS += ivfenc.h ivfenc.c
|
lossless_encoder.SRCS += ivfenc.h ivfenc.c
|
||||||
vp9_lossless_encoder.SRCS += tools_common.h tools_common.c
|
lossless_encoder.SRCS += tools_common.h tools_common.c
|
||||||
vp9_lossless_encoder.SRCS += video_common.h
|
lossless_encoder.SRCS += video_common.h
|
||||||
vp9_lossless_encoder.SRCS += video_writer.h video_writer.c
|
lossless_encoder.SRCS += video_writer.h video_writer.c
|
||||||
vp9_lossless_encoder.SRCS += vpx_ports/msvc.h
|
lossless_encoder.SRCS += vpx_ports/msvc.h
|
||||||
vp9_lossless_encoder.GUID = B63C7C88-5348-46DC-A5A6-CC151EF93366
|
lossless_encoder.GUID = B63C7C88-5348-46DC-A5A6-CC151EF93366
|
||||||
vp9_lossless_encoder.DESCRIPTION = Simplified lossless VP9 encoder
|
lossless_encoder.DESCRIPTION = Simplified lossless encoder
|
||||||
EXAMPLES-$(CONFIG_ENCODERS) += twopass_encoder.c
|
EXAMPLES-$(CONFIG_ENCODERS) += twopass_encoder.c
|
||||||
twopass_encoder.SRCS += ivfenc.h ivfenc.c
|
twopass_encoder.SRCS += ivfenc.h ivfenc.c
|
||||||
twopass_encoder.SRCS += tools_common.h tools_common.c
|
twopass_encoder.SRCS += tools_common.h tools_common.c
|
||||||
@@ -207,51 +180,30 @@ set_maps.SRCS += video_writer.h video_writer.c
|
|||||||
set_maps.SRCS += vpx_ports/msvc.h
|
set_maps.SRCS += vpx_ports/msvc.h
|
||||||
set_maps.GUID = ECB2D24D-98B8-4015-A465-A4AF3DCC145F
|
set_maps.GUID = ECB2D24D-98B8-4015-A465-A4AF3DCC145F
|
||||||
set_maps.DESCRIPTION = Set active and ROI maps
|
set_maps.DESCRIPTION = Set active and ROI maps
|
||||||
EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8cx_set_ref.c
|
|
||||||
vp8cx_set_ref.SRCS += ivfenc.h ivfenc.c
|
|
||||||
vp8cx_set_ref.SRCS += tools_common.h tools_common.c
|
|
||||||
vp8cx_set_ref.SRCS += video_common.h
|
|
||||||
vp8cx_set_ref.SRCS += video_writer.h video_writer.c
|
|
||||||
vp8cx_set_ref.SRCS += vpx_ports/msvc.h
|
|
||||||
vp8cx_set_ref.GUID = C5E31F7F-96F6-48BD-BD3E-10EBF6E8057A
|
|
||||||
vp8cx_set_ref.DESCRIPTION = VP8 set encoder reference frame
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_VP9_ENCODER),yes)
|
|
||||||
|
ifeq ($(CONFIG_VP10_ENCODER), yes)
|
||||||
ifeq ($(CONFIG_DECODERS),yes)
|
ifeq ($(CONFIG_DECODERS),yes)
|
||||||
EXAMPLES-yes += vp9cx_set_ref.c
|
EXAMPLES-yes += vpxcx_set_ref.c
|
||||||
vp9cx_set_ref.SRCS += ivfenc.h ivfenc.c
|
vpxcx_set_ref.SRCS += ivfenc.h ivfenc.c
|
||||||
vp9cx_set_ref.SRCS += tools_common.h tools_common.c
|
vpxcx_set_ref.SRCS += tools_common.h tools_common.c
|
||||||
vp9cx_set_ref.SRCS += video_common.h
|
vpxcx_set_ref.SRCS += video_common.h
|
||||||
vp9cx_set_ref.SRCS += video_writer.h video_writer.c
|
vpxcx_set_ref.SRCS += video_writer.h video_writer.c
|
||||||
vp9cx_set_ref.GUID = 65D7F14A-2EE6-4293-B958-AB5107A03B55
|
vpxcx_set_ref.GUID = 65D7F14A-2EE6-4293-B958-AB5107A03B55
|
||||||
vp9cx_set_ref.DESCRIPTION = VP9 set encoder reference frame
|
vpxcx_set_ref.DESCRIPTION = VP10 set encoder reference frame
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_MULTI_RES_ENCODING),yes)
|
|
||||||
ifeq ($(CONFIG_LIBYUV),yes)
|
|
||||||
EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8_multi_resolution_encoder.c
|
|
||||||
vp8_multi_resolution_encoder.SRCS += ivfenc.h ivfenc.c
|
|
||||||
vp8_multi_resolution_encoder.SRCS += tools_common.h tools_common.c
|
|
||||||
vp8_multi_resolution_encoder.SRCS += video_writer.h video_writer.c
|
|
||||||
vp8_multi_resolution_encoder.SRCS += vpx_ports/msvc.h
|
|
||||||
vp8_multi_resolution_encoder.SRCS += $(LIBYUV_SRCS)
|
|
||||||
vp8_multi_resolution_encoder.GUID = 04f8738e-63c8-423b-90fa-7c2703a374de
|
|
||||||
vp8_multi_resolution_encoder.DESCRIPTION = VP8 Multiple-resolution Encoding
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Handle extra library flags depending on codec configuration
|
# Handle extra library flags depending on codec configuration
|
||||||
|
|
||||||
# We should not link to math library (libm) on RVCT
|
# We should not link to math library (libm) on RVCT
|
||||||
# when building for bare-metal targets
|
# when building for bare-metal targets
|
||||||
ifeq ($(CONFIG_OS_SUPPORT), yes)
|
ifeq ($(CONFIG_OS_SUPPORT), yes)
|
||||||
CODEC_EXTRA_LIBS-$(CONFIG_VP8) += m
|
CODEC_EXTRA_LIBS-$(CONFIG_VP10) += m
|
||||||
CODEC_EXTRA_LIBS-$(CONFIG_VP9) += m
|
|
||||||
else
|
else
|
||||||
ifeq ($(CONFIG_GCC), yes)
|
ifeq ($(CONFIG_GCC), yes)
|
||||||
CODEC_EXTRA_LIBS-$(CONFIG_VP8) += m
|
CODEC_EXTRA_LIBS-$(CONFIG_VP10) += m
|
||||||
CODEC_EXTRA_LIBS-$(CONFIG_VP9) += m
|
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
#
|
#
|
||||||
@@ -268,10 +220,8 @@ ifeq ($(HAVE_ALT_TREE_LAYOUT),yes)
|
|||||||
INC_PATH-yes := $(SRC_PATH_BARE)/../include
|
INC_PATH-yes := $(SRC_PATH_BARE)/../include
|
||||||
else
|
else
|
||||||
LIB_PATH-yes += $(if $(BUILD_PFX),$(BUILD_PFX),.)
|
LIB_PATH-yes += $(if $(BUILD_PFX),$(BUILD_PFX),.)
|
||||||
INC_PATH-$(CONFIG_VP8_DECODER) += $(SRC_PATH_BARE)/vp8
|
INC_PATH-$(CONFIG_VP10_DECODER) += $(SRC_PATH_BARE)/vp10
|
||||||
INC_PATH-$(CONFIG_VP8_ENCODER) += $(SRC_PATH_BARE)/vp8
|
INC_PATH-$(CONFIG_VP10_ENCODER) += $(SRC_PATH_BARE)/vp10
|
||||||
INC_PATH-$(CONFIG_VP9_DECODER) += $(SRC_PATH_BARE)/vp9
|
|
||||||
INC_PATH-$(CONFIG_VP9_ENCODER) += $(SRC_PATH_BARE)/vp9
|
|
||||||
endif
|
endif
|
||||||
INC_PATH-$(CONFIG_LIBYUV) += $(SRC_PATH_BARE)/third_party/libyuv/include
|
INC_PATH-$(CONFIG_LIBYUV) += $(SRC_PATH_BARE)/third_party/libyuv/include
|
||||||
LIB_PATH := $(call enabled,LIB_PATH)
|
LIB_PATH := $(call enabled,LIB_PATH)
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ static void get_image_md5(const vpx_image_t *img, unsigned char digest[16]) {
|
|||||||
static void print_md5(FILE *stream, unsigned char digest[16]) {
|
static void print_md5(FILE *stream, unsigned char digest[16]) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 16; ++i) fprintf(stream, "%02x", digest[i]);
|
for (i = 0; i < 16; ++i)
|
||||||
|
fprintf(stream, "%02x", digest[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
@@ -85,10 +86,12 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc != 3) die("Invalid number of arguments.");
|
if (argc != 3)
|
||||||
|
die("Invalid number of arguments.");
|
||||||
|
|
||||||
reader = vpx_video_reader_open(argv[1]);
|
reader = vpx_video_reader_open(argv[1]);
|
||||||
if (!reader) die("Failed to open %s for reading.", argv[1]);
|
if (!reader)
|
||||||
|
die("Failed to open %s for reading.", argv[1]);
|
||||||
|
|
||||||
if (!(outfile = fopen(argv[2], "wb")))
|
if (!(outfile = fopen(argv[2], "wb")))
|
||||||
die("Failed to open %s for writing.", argv[2]);
|
die("Failed to open %s for writing.", argv[2]);
|
||||||
@@ -96,7 +99,8 @@ int main(int argc, char **argv) {
|
|||||||
info = vpx_video_reader_get_info(reader);
|
info = vpx_video_reader_get_info(reader);
|
||||||
|
|
||||||
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
|
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
|
||||||
if (!decoder) die("Unknown input codec.");
|
if (!decoder)
|
||||||
|
die("Unknown input codec.");
|
||||||
|
|
||||||
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
|
||||||
|
|
||||||
@@ -107,8 +111,8 @@ int main(int argc, char **argv) {
|
|||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
vpx_image_t *img = NULL;
|
vpx_image_t *img = NULL;
|
||||||
size_t frame_size = 0;
|
size_t frame_size = 0;
|
||||||
const unsigned char *frame =
|
const unsigned char *frame = vpx_video_reader_get_frame(reader,
|
||||||
vpx_video_reader_get_frame(reader, &frame_size);
|
&frame_size);
|
||||||
if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
|
if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
|
||||||
die_codec(&codec, "Failed to decode frame");
|
die_codec(&codec, "Failed to decode frame");
|
||||||
|
|
||||||
@@ -117,13 +121,14 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
get_image_md5(img, digest);
|
get_image_md5(img, digest);
|
||||||
print_md5(outfile, digest);
|
print_md5(outfile, digest);
|
||||||
fprintf(outfile, " img-%dx%d-%04d.i420\n", img->d_w, img->d_h,
|
fprintf(outfile, " img-%dx%d-%04d.i420\n",
|
||||||
++frame_cnt);
|
img->d_w, img->d_h, ++frame_cnt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Processed %d frames.\n", frame_cnt);
|
printf("Processed %d frames.\n", frame_cnt);
|
||||||
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
|
if (vpx_codec_destroy(&codec))
|
||||||
|
die_codec(&codec, "Failed to destroy codec.");
|
||||||
|
|
||||||
vpx_video_reader_close(reader);
|
vpx_video_reader_close(reader);
|
||||||
|
|
||||||
|
|||||||
@@ -84,16 +84,18 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc != 4) die("Invalid number of arguments.");
|
if (argc != 4)
|
||||||
|
die("Invalid number of arguments.");
|
||||||
|
|
||||||
reader = vpx_video_reader_open(argv[1]);
|
reader = vpx_video_reader_open(argv[1]);
|
||||||
if (!reader) die("Failed to open %s for reading.", argv[1]);
|
if (!reader)
|
||||||
|
die("Failed to open %s for reading.", argv[1]);
|
||||||
|
|
||||||
if (!(outfile = fopen(argv[2], "wb")))
|
if (!(outfile = fopen(argv[2], "wb")))
|
||||||
die("Failed to open %s for writing.", argv[2]);
|
die("Failed to open %s for writing.", argv[2]);
|
||||||
|
|
||||||
n = (int)strtol(argv[3], &nptr, 0);
|
n = strtol(argv[3], &nptr, 0);
|
||||||
m = (int)strtol(nptr + 1, NULL, 0);
|
m = strtol(nptr + 1, NULL, 0);
|
||||||
is_range = (*nptr == '-');
|
is_range = (*nptr == '-');
|
||||||
if (!n || !m || (*nptr != '-' && *nptr != '/'))
|
if (!n || !m || (*nptr != '-' && *nptr != '/'))
|
||||||
die("Couldn't parse pattern %s.\n", argv[3]);
|
die("Couldn't parse pattern %s.\n", argv[3]);
|
||||||
@@ -101,7 +103,8 @@ int main(int argc, char **argv) {
|
|||||||
info = vpx_video_reader_get_info(reader);
|
info = vpx_video_reader_get_info(reader);
|
||||||
|
|
||||||
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
|
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
|
||||||
if (!decoder) die("Unknown input codec.");
|
if (!decoder)
|
||||||
|
die("Unknown input codec.");
|
||||||
|
|
||||||
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
|
||||||
|
|
||||||
@@ -113,8 +116,8 @@ int main(int argc, char **argv) {
|
|||||||
vpx_image_t *img = NULL;
|
vpx_image_t *img = NULL;
|
||||||
size_t frame_size = 0;
|
size_t frame_size = 0;
|
||||||
int skip;
|
int skip;
|
||||||
const unsigned char *frame =
|
const unsigned char *frame = vpx_video_reader_get_frame(reader,
|
||||||
vpx_video_reader_get_frame(reader, &frame_size);
|
&frame_size);
|
||||||
if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
|
if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
|
||||||
die_codec(&codec, "Failed to decode frame.");
|
die_codec(&codec, "Failed to decode frame.");
|
||||||
|
|
||||||
@@ -136,7 +139,8 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("Processed %d frames.\n", frame_cnt);
|
printf("Processed %d frames.\n", frame_cnt);
|
||||||
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
|
if (vpx_codec_destroy(&codec))
|
||||||
|
die_codec(&codec, "Failed to destroy codec.");
|
||||||
|
|
||||||
printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
|
printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
|
||||||
info->frame_width, info->frame_height, argv[2]);
|
info->frame_width, info->frame_height, argv[2]);
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
#include "vpx/vpx_encoder.h"
|
#include "vpx/vpx_encoder.h"
|
||||||
#include "vpx/vp8cx.h"
|
#include "vpx/vp8cx.h"
|
||||||
#include "vp9/common/vp9_common.h"
|
|
||||||
|
|
||||||
#include "../tools_common.h"
|
#include "../tools_common.h"
|
||||||
#include "../video_writer.h"
|
#include "../video_writer.h"
|
||||||
@@ -22,28 +21,32 @@
|
|||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
|
|
||||||
void usage_exit(void) {
|
void usage_exit(void) {
|
||||||
fprintf(stderr,
|
fprintf(stderr, "lossless_encoder: Example demonstrating lossless "
|
||||||
"vp9_lossless_encoder: Example demonstrating VP9 lossless "
|
|
||||||
"encoding feature. Supports raw input only.\n");
|
"encoding feature. Supports raw input only.\n");
|
||||||
fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile>\n", exec_name);
|
fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile>\n", exec_name);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img,
|
static int encode_frame(vpx_codec_ctx_t *codec,
|
||||||
int frame_index, int flags, VpxVideoWriter *writer) {
|
vpx_image_t *img,
|
||||||
|
int frame_index,
|
||||||
|
int flags,
|
||||||
|
VpxVideoWriter *writer) {
|
||||||
int got_pkts = 0;
|
int got_pkts = 0;
|
||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
const vpx_codec_cx_pkt_t *pkt = NULL;
|
const vpx_codec_cx_pkt_t *pkt = NULL;
|
||||||
const vpx_codec_err_t res =
|
const vpx_codec_err_t res = vpx_codec_encode(codec, img, frame_index, 1,
|
||||||
vpx_codec_encode(codec, img, frame_index, 1, flags, VPX_DL_GOOD_QUALITY);
|
flags, VPX_DL_GOOD_QUALITY);
|
||||||
if (res != VPX_CODEC_OK) die_codec(codec, "Failed to encode frame");
|
if (res != VPX_CODEC_OK)
|
||||||
|
die_codec(codec, "Failed to encode frame");
|
||||||
|
|
||||||
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
|
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
|
||||||
got_pkts = 1;
|
got_pkts = 1;
|
||||||
|
|
||||||
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
||||||
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
||||||
if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf,
|
if (!vpx_video_writer_write_frame(writer,
|
||||||
|
pkt->data.frame.buf,
|
||||||
pkt->data.frame.sz,
|
pkt->data.frame.sz,
|
||||||
pkt->data.frame.pts)) {
|
pkt->data.frame.pts)) {
|
||||||
die_codec(codec, "Failed to write compressed frame");
|
die_codec(codec, "Failed to write compressed frame");
|
||||||
@@ -63,28 +66,30 @@ int main(int argc, char **argv) {
|
|||||||
int frame_count = 0;
|
int frame_count = 0;
|
||||||
vpx_image_t raw;
|
vpx_image_t raw;
|
||||||
vpx_codec_err_t res;
|
vpx_codec_err_t res;
|
||||||
VpxVideoInfo info;
|
VpxVideoInfo info = {0};
|
||||||
VpxVideoWriter *writer = NULL;
|
VpxVideoWriter *writer = NULL;
|
||||||
const VpxInterface *encoder = NULL;
|
const VpxInterface *encoder = NULL;
|
||||||
const int fps = 30;
|
const int fps = 30;
|
||||||
|
|
||||||
vp9_zero(info);
|
|
||||||
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc < 5) die("Invalid number of arguments");
|
if (argc < 5)
|
||||||
|
die("Invalid number of arguments");
|
||||||
|
|
||||||
encoder = get_vpx_encoder_by_name("vp9");
|
encoder = get_vpx_encoder_by_name("vp9");
|
||||||
if (!encoder) die("Unsupported codec.");
|
if (!encoder)
|
||||||
|
die("Unsupported codec.");
|
||||||
|
|
||||||
info.codec_fourcc = encoder->fourcc;
|
info.codec_fourcc = encoder->fourcc;
|
||||||
info.frame_width = (int)strtol(argv[1], NULL, 0);
|
info.frame_width = strtol(argv[1], NULL, 0);
|
||||||
info.frame_height = (int)strtol(argv[2], NULL, 0);
|
info.frame_height = strtol(argv[2], NULL, 0);
|
||||||
info.time_base.numerator = 1;
|
info.time_base.numerator = 1;
|
||||||
info.time_base.denominator = fps;
|
info.time_base.denominator = fps;
|
||||||
|
|
||||||
if (info.frame_width <= 0 || info.frame_height <= 0 ||
|
if (info.frame_width <= 0 ||
|
||||||
(info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
|
info.frame_height <= 0 ||
|
||||||
|
(info.frame_width % 2) != 0 ||
|
||||||
|
(info.frame_height % 2) != 0) {
|
||||||
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +101,8 @@ int main(int argc, char **argv) {
|
|||||||
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
||||||
|
|
||||||
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
||||||
if (res) die_codec(&codec, "Failed to get default codec config.");
|
if (res)
|
||||||
|
die_codec(&codec, "Failed to get default codec config.");
|
||||||
|
|
||||||
cfg.g_w = info.frame_width;
|
cfg.g_w = info.frame_width;
|
||||||
cfg.g_h = info.frame_height;
|
cfg.g_h = info.frame_height;
|
||||||
@@ -104,7 +110,8 @@ int main(int argc, char **argv) {
|
|||||||
cfg.g_timebase.den = info.time_base.denominator;
|
cfg.g_timebase.den = info.time_base.denominator;
|
||||||
|
|
||||||
writer = vpx_video_writer_open(argv[4], kContainerIVF, &info);
|
writer = vpx_video_writer_open(argv[4], kContainerIVF, &info);
|
||||||
if (!writer) die("Failed to open %s for writing.", argv[4]);
|
if (!writer)
|
||||||
|
die("Failed to open %s for writing.", argv[4]);
|
||||||
|
|
||||||
if (!(infile = fopen(argv[3], "rb")))
|
if (!(infile = fopen(argv[3], "rb")))
|
||||||
die("Failed to open %s for reading.", argv[3]);
|
die("Failed to open %s for reading.", argv[3]);
|
||||||
@@ -121,15 +128,15 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Flush encoder.
|
// Flush encoder.
|
||||||
while (encode_frame(&codec, NULL, -1, 0, writer)) {
|
while (encode_frame(&codec, NULL, -1, 0, writer)) {}
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
fclose(infile);
|
fclose(infile);
|
||||||
printf("Processed %d frames.\n", frame_count);
|
printf("Processed %d frames.\n", frame_count);
|
||||||
|
|
||||||
vpx_img_free(&raw);
|
vpx_img_free(&raw);
|
||||||
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
|
if (vpx_codec_destroy(&codec))
|
||||||
|
die_codec(&codec, "Failed to destroy codec.");
|
||||||
|
|
||||||
vpx_video_writer_close(writer);
|
vpx_video_writer_close(writer);
|
||||||
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Postprocessing Decoder
|
|
||||||
// ======================
|
|
||||||
//
|
|
||||||
// This example adds postprocessing to the simple decoder loop.
|
|
||||||
//
|
|
||||||
// Initializing Postprocessing
|
|
||||||
// ---------------------------
|
|
||||||
// You must inform the codec that you might request postprocessing at
|
|
||||||
// initialization time. This is done by passing the VPX_CODEC_USE_POSTPROC
|
|
||||||
// flag to `vpx_codec_dec_init`. If the codec does not support
|
|
||||||
// postprocessing, this call will return VPX_CODEC_INCAPABLE. For
|
|
||||||
// demonstration purposes, we also fall back to default initialization if
|
|
||||||
// the codec does not provide support.
|
|
||||||
//
|
|
||||||
// Using Adaptive Postprocessing
|
|
||||||
// -----------------------------
|
|
||||||
// VP6 provides "adaptive postprocessing." It will automatically select the
|
|
||||||
// best postprocessing filter on a frame by frame basis based on the amount
|
|
||||||
// of time remaining before the user's specified deadline expires. The
|
|
||||||
// special value 0 indicates that the codec should take as long as
|
|
||||||
// necessary to provide the best quality frame. This example gives the
|
|
||||||
// codec 15ms (15000us) to return a frame. Remember that this is a soft
|
|
||||||
// deadline, and the codec may exceed it doing its regular processing. In
|
|
||||||
// these cases, no additional postprocessing will be done.
|
|
||||||
//
|
|
||||||
// Codec Specific Postprocessing Controls
|
|
||||||
// --------------------------------------
|
|
||||||
// Some codecs provide fine grained controls over their built-in
|
|
||||||
// postprocessors. VP8 is one example. The following sample code toggles
|
|
||||||
// postprocessing on and off every 15 frames.
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "vpx/vp8dx.h"
|
|
||||||
#include "vpx/vpx_decoder.h"
|
|
||||||
|
|
||||||
#include "../tools_common.h"
|
|
||||||
#include "../video_reader.h"
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
|
|
||||||
static const char *exec_name;
|
|
||||||
|
|
||||||
void usage_exit(void) {
|
|
||||||
fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
int frame_cnt = 0;
|
|
||||||
FILE *outfile = NULL;
|
|
||||||
vpx_codec_ctx_t codec;
|
|
||||||
vpx_codec_err_t res;
|
|
||||||
VpxVideoReader *reader = NULL;
|
|
||||||
const VpxInterface *decoder = NULL;
|
|
||||||
const VpxVideoInfo *info = NULL;
|
|
||||||
|
|
||||||
exec_name = argv[0];
|
|
||||||
|
|
||||||
if (argc != 3) die("Invalid number of arguments.");
|
|
||||||
|
|
||||||
reader = vpx_video_reader_open(argv[1]);
|
|
||||||
if (!reader) die("Failed to open %s for reading.", argv[1]);
|
|
||||||
|
|
||||||
if (!(outfile = fopen(argv[2], "wb")))
|
|
||||||
die("Failed to open %s for writing", argv[2]);
|
|
||||||
|
|
||||||
info = vpx_video_reader_get_info(reader);
|
|
||||||
|
|
||||||
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
|
|
||||||
if (!decoder) die("Unknown input codec.");
|
|
||||||
|
|
||||||
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
|
|
||||||
|
|
||||||
res = vpx_codec_dec_init(&codec, decoder->codec_interface(), NULL,
|
|
||||||
VPX_CODEC_USE_POSTPROC);
|
|
||||||
if (res == VPX_CODEC_INCAPABLE)
|
|
||||||
die_codec(&codec, "Postproc not supported by this decoder.");
|
|
||||||
|
|
||||||
if (res) die_codec(&codec, "Failed to initialize decoder.");
|
|
||||||
|
|
||||||
while (vpx_video_reader_read_frame(reader)) {
|
|
||||||
vpx_codec_iter_t iter = NULL;
|
|
||||||
vpx_image_t *img = NULL;
|
|
||||||
size_t frame_size = 0;
|
|
||||||
const unsigned char *frame =
|
|
||||||
vpx_video_reader_get_frame(reader, &frame_size);
|
|
||||||
|
|
||||||
++frame_cnt;
|
|
||||||
|
|
||||||
if (frame_cnt % 30 == 1) {
|
|
||||||
vp8_postproc_cfg_t pp = { 0, 0, 0 };
|
|
||||||
|
|
||||||
if (vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp))
|
|
||||||
die_codec(&codec, "Failed to turn off postproc.");
|
|
||||||
} else if (frame_cnt % 30 == 16) {
|
|
||||||
vp8_postproc_cfg_t pp = { VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE, 4,
|
|
||||||
0 };
|
|
||||||
if (vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp))
|
|
||||||
die_codec(&codec, "Failed to turn on postproc.");
|
|
||||||
};
|
|
||||||
|
|
||||||
// Decode the frame with 15ms deadline
|
|
||||||
if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 15000))
|
|
||||||
die_codec(&codec, "Failed to decode frame");
|
|
||||||
|
|
||||||
while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL) {
|
|
||||||
vpx_img_write(img, outfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Processed %d frames.\n", frame_cnt);
|
|
||||||
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
|
|
||||||
|
|
||||||
printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
|
|
||||||
info->frame_width, info->frame_height, argv[2]);
|
|
||||||
|
|
||||||
vpx_video_reader_close(reader);
|
|
||||||
|
|
||||||
fclose(outfile);
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
@@ -34,8 +34,10 @@ void usage_exit(void) {
|
|||||||
|
|
||||||
static int parse_dim(char *v, int *width, int *height) {
|
static int parse_dim(char *v, int *width, int *height) {
|
||||||
char *x = strchr(v, 'x');
|
char *x = strchr(v, 'x');
|
||||||
if (x == NULL) x = strchr(v, 'X');
|
if (x == NULL)
|
||||||
if (x == NULL) return 0;
|
x = strchr(v, 'X');
|
||||||
|
if (x == NULL)
|
||||||
|
return 0;
|
||||||
*width = atoi(v);
|
*width = atoi(v);
|
||||||
*height = atoi(&x[1]);
|
*height = atoi(&x[1]);
|
||||||
if (*width <= 0 || *height <= 0)
|
if (*width <= 0 || *height <= 0)
|
||||||
@@ -91,8 +93,10 @@ int main(int argc, char *argv[]) {
|
|||||||
else
|
else
|
||||||
frames = INT_MAX;
|
frames = INT_MAX;
|
||||||
|
|
||||||
printf("Input size: %dx%d\n", width, height);
|
printf("Input size: %dx%d\n",
|
||||||
printf("Target size: %dx%d, Frames: ", target_width, target_height);
|
width, height);
|
||||||
|
printf("Target size: %dx%d, Frames: ",
|
||||||
|
target_width, target_height);
|
||||||
if (frames == INT_MAX)
|
if (frames == INT_MAX)
|
||||||
printf("All\n");
|
printf("All\n");
|
||||||
else
|
else
|
||||||
@@ -106,10 +110,13 @@ int main(int argc, char *argv[]) {
|
|||||||
outbuf_v = outbuf_u + target_width * target_height / 4;
|
outbuf_v = outbuf_u + target_width * target_height / 4;
|
||||||
f = 0;
|
f = 0;
|
||||||
while (f < frames) {
|
while (f < frames) {
|
||||||
if (fread(inbuf, width * height * 3 / 2, 1, fpin) != 1) break;
|
if (fread(inbuf, width * height * 3 / 2, 1, fpin) != 1)
|
||||||
vp9_resize_frame420(inbuf, width, inbuf_u, inbuf_v, width / 2, height,
|
break;
|
||||||
width, outbuf, target_width, outbuf_u, outbuf_v,
|
vp9_resize_frame420(inbuf, width, inbuf_u, inbuf_v, width / 2,
|
||||||
target_width / 2, target_height, target_width);
|
height, width,
|
||||||
|
outbuf, target_width, outbuf_u, outbuf_v,
|
||||||
|
target_width / 2,
|
||||||
|
target_height, target_width);
|
||||||
fwrite(outbuf, target_width * target_height * 3 / 2, 1, fpout);
|
fwrite(outbuf, target_width * target_height * 3 / 2, 1, fpout);
|
||||||
f++;
|
f++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// VP8 Set Active and ROI Maps
|
// VP8 Set Active and ROI Maps
|
||||||
// ===========================
|
// ===========================
|
||||||
//
|
//
|
||||||
@@ -85,7 +86,8 @@ static void set_roi_map(const vpx_codec_enc_cfg_t *cfg,
|
|||||||
roi.static_threshold[3] = 0;
|
roi.static_threshold[3] = 0;
|
||||||
|
|
||||||
roi.roi_map = (uint8_t *)malloc(roi.rows * roi.cols);
|
roi.roi_map = (uint8_t *)malloc(roi.rows * roi.cols);
|
||||||
for (i = 0; i < roi.rows * roi.cols; ++i) roi.roi_map[i] = i % 4;
|
for (i = 0; i < roi.rows * roi.cols; ++i)
|
||||||
|
roi.roi_map[i] = i % 4;
|
||||||
|
|
||||||
if (vpx_codec_control(codec, VP8E_SET_ROI_MAP, &roi))
|
if (vpx_codec_control(codec, VP8E_SET_ROI_MAP, &roi))
|
||||||
die_codec(codec, "Failed to set ROI map");
|
die_codec(codec, "Failed to set ROI map");
|
||||||
@@ -102,7 +104,8 @@ static void set_active_map(const vpx_codec_enc_cfg_t *cfg,
|
|||||||
map.cols = (cfg->g_w + 15) / 16;
|
map.cols = (cfg->g_w + 15) / 16;
|
||||||
|
|
||||||
map.active_map = (uint8_t *)malloc(map.rows * map.cols);
|
map.active_map = (uint8_t *)malloc(map.rows * map.cols);
|
||||||
for (i = 0; i < map.rows * map.cols; ++i) map.active_map[i] = i % 2;
|
for (i = 0; i < map.rows * map.cols; ++i)
|
||||||
|
map.active_map[i] = i % 2;
|
||||||
|
|
||||||
if (vpx_codec_control(codec, VP8E_SET_ACTIVEMAP, &map))
|
if (vpx_codec_control(codec, VP8E_SET_ACTIVEMAP, &map))
|
||||||
die_codec(codec, "Failed to set active map");
|
die_codec(codec, "Failed to set active map");
|
||||||
@@ -122,21 +125,25 @@ static void unset_active_map(const vpx_codec_enc_cfg_t *cfg,
|
|||||||
die_codec(codec, "Failed to set active map");
|
die_codec(codec, "Failed to set active map");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img,
|
static int encode_frame(vpx_codec_ctx_t *codec,
|
||||||
int frame_index, VpxVideoWriter *writer) {
|
vpx_image_t *img,
|
||||||
|
int frame_index,
|
||||||
|
VpxVideoWriter *writer) {
|
||||||
int got_pkts = 0;
|
int got_pkts = 0;
|
||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
const vpx_codec_cx_pkt_t *pkt = NULL;
|
const vpx_codec_cx_pkt_t *pkt = NULL;
|
||||||
const vpx_codec_err_t res =
|
const vpx_codec_err_t res = vpx_codec_encode(codec, img, frame_index, 1, 0,
|
||||||
vpx_codec_encode(codec, img, frame_index, 1, 0, VPX_DL_GOOD_QUALITY);
|
VPX_DL_GOOD_QUALITY);
|
||||||
if (res != VPX_CODEC_OK) die_codec(codec, "Failed to encode frame");
|
if (res != VPX_CODEC_OK)
|
||||||
|
die_codec(codec, "Failed to encode frame");
|
||||||
|
|
||||||
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
|
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
|
||||||
got_pkts = 1;
|
got_pkts = 1;
|
||||||
|
|
||||||
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
||||||
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
||||||
if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf,
|
if (!vpx_video_writer_write_frame(writer,
|
||||||
|
pkt->data.frame.buf,
|
||||||
pkt->data.frame.sz,
|
pkt->data.frame.sz,
|
||||||
pkt->data.frame.pts)) {
|
pkt->data.frame.pts)) {
|
||||||
die_codec(codec, "Failed to write compressed frame");
|
die_codec(codec, "Failed to write compressed frame");
|
||||||
@@ -164,7 +171,8 @@ int main(int argc, char **argv) {
|
|||||||
const double bits_per_pixel_per_frame = 0.067;
|
const double bits_per_pixel_per_frame = 0.067;
|
||||||
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
if (argc != 6) die("Invalid number of arguments");
|
if (argc != 6)
|
||||||
|
die("Invalid number of arguments");
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
|
|
||||||
@@ -174,13 +182,15 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
assert(encoder != NULL);
|
assert(encoder != NULL);
|
||||||
info.codec_fourcc = encoder->fourcc;
|
info.codec_fourcc = encoder->fourcc;
|
||||||
info.frame_width = (int)strtol(argv[2], NULL, 0);
|
info.frame_width = strtol(argv[2], NULL, 0);
|
||||||
info.frame_height = (int)strtol(argv[3], NULL, 0);
|
info.frame_height = strtol(argv[3], NULL, 0);
|
||||||
info.time_base.numerator = 1;
|
info.time_base.numerator = 1;
|
||||||
info.time_base.denominator = fps;
|
info.time_base.denominator = fps;
|
||||||
|
|
||||||
if (info.frame_width <= 0 || info.frame_height <= 0 ||
|
if (info.frame_width <= 0 ||
|
||||||
(info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
|
info.frame_height <= 0 ||
|
||||||
|
(info.frame_width % 2) != 0 ||
|
||||||
|
(info.frame_height % 2) != 0) {
|
||||||
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,18 +202,20 @@ int main(int argc, char **argv) {
|
|||||||
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
||||||
|
|
||||||
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
||||||
if (res) die_codec(&codec, "Failed to get default codec config.");
|
if (res)
|
||||||
|
die_codec(&codec, "Failed to get default codec config.");
|
||||||
|
|
||||||
cfg.g_w = info.frame_width;
|
cfg.g_w = info.frame_width;
|
||||||
cfg.g_h = info.frame_height;
|
cfg.g_h = info.frame_height;
|
||||||
cfg.g_timebase.num = info.time_base.numerator;
|
cfg.g_timebase.num = info.time_base.numerator;
|
||||||
cfg.g_timebase.den = info.time_base.denominator;
|
cfg.g_timebase.den = info.time_base.denominator;
|
||||||
cfg.rc_target_bitrate =
|
cfg.rc_target_bitrate = (unsigned int)(bits_per_pixel_per_frame * cfg.g_w *
|
||||||
(unsigned int)(bits_per_pixel_per_frame * cfg.g_w * cfg.g_h * fps / 1000);
|
cfg.g_h * fps / 1000);
|
||||||
cfg.g_lag_in_frames = 0;
|
cfg.g_lag_in_frames = 0;
|
||||||
|
|
||||||
writer = vpx_video_writer_open(argv[5], kContainerIVF, &info);
|
writer = vpx_video_writer_open(argv[5], kContainerIVF, &info);
|
||||||
if (!writer) die("Failed to open %s for writing.", argv[5]);
|
if (!writer)
|
||||||
|
die("Failed to open %s for writing.", argv[5]);
|
||||||
|
|
||||||
if (!(infile = fopen(argv[4], "rb")))
|
if (!(infile = fopen(argv[4], "rb")))
|
||||||
die("Failed to open %s for reading.", argv[4]);
|
die("Failed to open %s for reading.", argv[4]);
|
||||||
@@ -227,15 +239,15 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Flush encoder.
|
// Flush encoder.
|
||||||
while (encode_frame(&codec, NULL, -1, writer)) {
|
while (encode_frame(&codec, NULL, -1, writer)) {}
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
fclose(infile);
|
fclose(infile);
|
||||||
printf("Processed %d frames.\n", frame_count);
|
printf("Processed %d frames.\n", frame_count);
|
||||||
|
|
||||||
vpx_img_free(&raw);
|
vpx_img_free(&raw);
|
||||||
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
|
if (vpx_codec_destroy(&codec))
|
||||||
|
die_codec(&codec, "Failed to destroy codec.");
|
||||||
|
|
||||||
vpx_video_writer_close(writer);
|
vpx_video_writer_close(writer);
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// Simple Decoder
|
// Simple Decoder
|
||||||
// ==============
|
// ==============
|
||||||
//
|
//
|
||||||
@@ -102,10 +103,12 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc != 3) die("Invalid number of arguments.");
|
if (argc != 3)
|
||||||
|
die("Invalid number of arguments.");
|
||||||
|
|
||||||
reader = vpx_video_reader_open(argv[1]);
|
reader = vpx_video_reader_open(argv[1]);
|
||||||
if (!reader) die("Failed to open %s for reading.", argv[1]);
|
if (!reader)
|
||||||
|
die("Failed to open %s for reading.", argv[1]);
|
||||||
|
|
||||||
if (!(outfile = fopen(argv[2], "wb")))
|
if (!(outfile = fopen(argv[2], "wb")))
|
||||||
die("Failed to open %s for writing.", argv[2]);
|
die("Failed to open %s for writing.", argv[2]);
|
||||||
@@ -113,7 +116,8 @@ int main(int argc, char **argv) {
|
|||||||
info = vpx_video_reader_get_info(reader);
|
info = vpx_video_reader_get_info(reader);
|
||||||
|
|
||||||
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
|
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
|
||||||
if (!decoder) die("Unknown input codec.");
|
if (!decoder)
|
||||||
|
die("Unknown input codec.");
|
||||||
|
|
||||||
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
|
||||||
|
|
||||||
@@ -124,8 +128,8 @@ int main(int argc, char **argv) {
|
|||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
vpx_image_t *img = NULL;
|
vpx_image_t *img = NULL;
|
||||||
size_t frame_size = 0;
|
size_t frame_size = 0;
|
||||||
const unsigned char *frame =
|
const unsigned char *frame = vpx_video_reader_get_frame(reader,
|
||||||
vpx_video_reader_get_frame(reader, &frame_size);
|
&frame_size);
|
||||||
if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
|
if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
|
||||||
die_codec(&codec, "Failed to decode frame.");
|
die_codec(&codec, "Failed to decode frame.");
|
||||||
|
|
||||||
@@ -136,7 +140,8 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("Processed %d frames.\n", frame_cnt);
|
printf("Processed %d frames.\n", frame_cnt);
|
||||||
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
|
if (vpx_codec_destroy(&codec))
|
||||||
|
die_codec(&codec, "Failed to destroy codec");
|
||||||
|
|
||||||
printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
|
printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
|
||||||
info->frame_width, info->frame_height, argv[2]);
|
info->frame_width, info->frame_height, argv[2]);
|
||||||
|
|||||||
@@ -115,21 +115,26 @@ void usage_exit(void) {
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img,
|
static int encode_frame(vpx_codec_ctx_t *codec,
|
||||||
int frame_index, int flags, VpxVideoWriter *writer) {
|
vpx_image_t *img,
|
||||||
|
int frame_index,
|
||||||
|
int flags,
|
||||||
|
VpxVideoWriter *writer) {
|
||||||
int got_pkts = 0;
|
int got_pkts = 0;
|
||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
const vpx_codec_cx_pkt_t *pkt = NULL;
|
const vpx_codec_cx_pkt_t *pkt = NULL;
|
||||||
const vpx_codec_err_t res =
|
const vpx_codec_err_t res = vpx_codec_encode(codec, img, frame_index, 1,
|
||||||
vpx_codec_encode(codec, img, frame_index, 1, flags, VPX_DL_GOOD_QUALITY);
|
flags, VPX_DL_GOOD_QUALITY);
|
||||||
if (res != VPX_CODEC_OK) die_codec(codec, "Failed to encode frame");
|
if (res != VPX_CODEC_OK)
|
||||||
|
die_codec(codec, "Failed to encode frame");
|
||||||
|
|
||||||
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
|
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
|
||||||
got_pkts = 1;
|
got_pkts = 1;
|
||||||
|
|
||||||
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
||||||
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
||||||
if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf,
|
if (!vpx_video_writer_write_frame(writer,
|
||||||
|
pkt->data.frame.buf,
|
||||||
pkt->data.frame.sz,
|
pkt->data.frame.sz,
|
||||||
pkt->data.frame.pts)) {
|
pkt->data.frame.pts)) {
|
||||||
die_codec(codec, "Failed to write compressed frame");
|
die_codec(codec, "Failed to write compressed frame");
|
||||||
@@ -150,7 +155,7 @@ int main(int argc, char **argv) {
|
|||||||
int frame_count = 0;
|
int frame_count = 0;
|
||||||
vpx_image_t raw;
|
vpx_image_t raw;
|
||||||
vpx_codec_err_t res;
|
vpx_codec_err_t res;
|
||||||
VpxVideoInfo info = { 0, 0, 0, { 0, 0 } };
|
VpxVideoInfo info = {0};
|
||||||
VpxVideoWriter *writer = NULL;
|
VpxVideoWriter *writer = NULL;
|
||||||
const VpxInterface *encoder = NULL;
|
const VpxInterface *encoder = NULL;
|
||||||
const int fps = 30;
|
const int fps = 30;
|
||||||
@@ -167,7 +172,8 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc != 9) die("Invalid number of arguments");
|
if (argc != 9)
|
||||||
|
die("Invalid number of arguments");
|
||||||
|
|
||||||
codec_arg = argv[1];
|
codec_arg = argv[1];
|
||||||
width_arg = argv[2];
|
width_arg = argv[2];
|
||||||
@@ -175,19 +181,22 @@ int main(int argc, char **argv) {
|
|||||||
infile_arg = argv[4];
|
infile_arg = argv[4];
|
||||||
outfile_arg = argv[5];
|
outfile_arg = argv[5];
|
||||||
keyframe_interval_arg = argv[6];
|
keyframe_interval_arg = argv[6];
|
||||||
max_frames = (int)strtol(argv[8], NULL, 0);
|
max_frames = strtol(argv[8], NULL, 0);
|
||||||
|
|
||||||
encoder = get_vpx_encoder_by_name(codec_arg);
|
encoder = get_vpx_encoder_by_name(codec_arg);
|
||||||
if (!encoder) die("Unsupported codec.");
|
if (!encoder)
|
||||||
|
die("Unsupported codec.");
|
||||||
|
|
||||||
info.codec_fourcc = encoder->fourcc;
|
info.codec_fourcc = encoder->fourcc;
|
||||||
info.frame_width = (int)strtol(width_arg, NULL, 0);
|
info.frame_width = strtol(width_arg, NULL, 0);
|
||||||
info.frame_height = (int)strtol(height_arg, NULL, 0);
|
info.frame_height = strtol(height_arg, NULL, 0);
|
||||||
info.time_base.numerator = 1;
|
info.time_base.numerator = 1;
|
||||||
info.time_base.denominator = fps;
|
info.time_base.denominator = fps;
|
||||||
|
|
||||||
if (info.frame_width <= 0 || info.frame_height <= 0 ||
|
if (info.frame_width <= 0 ||
|
||||||
(info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
|
info.frame_height <= 0 ||
|
||||||
|
(info.frame_width % 2) != 0 ||
|
||||||
|
(info.frame_height % 2) != 0) {
|
||||||
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,23 +205,26 @@ int main(int argc, char **argv) {
|
|||||||
die("Failed to allocate image.");
|
die("Failed to allocate image.");
|
||||||
}
|
}
|
||||||
|
|
||||||
keyframe_interval = (int)strtol(keyframe_interval_arg, NULL, 0);
|
keyframe_interval = strtol(keyframe_interval_arg, NULL, 0);
|
||||||
if (keyframe_interval < 0) die("Invalid keyframe interval value.");
|
if (keyframe_interval < 0)
|
||||||
|
die("Invalid keyframe interval value.");
|
||||||
|
|
||||||
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
||||||
|
|
||||||
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
||||||
if (res) die_codec(&codec, "Failed to get default codec config.");
|
if (res)
|
||||||
|
die_codec(&codec, "Failed to get default codec config.");
|
||||||
|
|
||||||
cfg.g_w = info.frame_width;
|
cfg.g_w = info.frame_width;
|
||||||
cfg.g_h = info.frame_height;
|
cfg.g_h = info.frame_height;
|
||||||
cfg.g_timebase.num = info.time_base.numerator;
|
cfg.g_timebase.num = info.time_base.numerator;
|
||||||
cfg.g_timebase.den = info.time_base.denominator;
|
cfg.g_timebase.den = info.time_base.denominator;
|
||||||
cfg.rc_target_bitrate = bitrate;
|
cfg.rc_target_bitrate = bitrate;
|
||||||
cfg.g_error_resilient = (vpx_codec_er_flags_t)strtoul(argv[7], NULL, 0);
|
cfg.g_error_resilient = strtol(argv[7], NULL, 0);
|
||||||
|
|
||||||
writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info);
|
writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info);
|
||||||
if (!writer) die("Failed to open %s for writing.", outfile_arg);
|
if (!writer)
|
||||||
|
die("Failed to open %s for writing.", outfile_arg);
|
||||||
|
|
||||||
if (!(infile = fopen(infile_arg, "rb")))
|
if (!(infile = fopen(infile_arg, "rb")))
|
||||||
die("Failed to open %s for reading.", infile_arg);
|
die("Failed to open %s for reading.", infile_arg);
|
||||||
@@ -227,19 +239,20 @@ int main(int argc, char **argv) {
|
|||||||
flags |= VPX_EFLAG_FORCE_KF;
|
flags |= VPX_EFLAG_FORCE_KF;
|
||||||
encode_frame(&codec, &raw, frame_count++, flags, writer);
|
encode_frame(&codec, &raw, frame_count++, flags, writer);
|
||||||
frames_encoded++;
|
frames_encoded++;
|
||||||
if (max_frames > 0 && frames_encoded >= max_frames) break;
|
if (max_frames > 0 && frames_encoded >= max_frames)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush encoder.
|
// Flush encoder.
|
||||||
while (encode_frame(&codec, NULL, -1, 0, writer)) {
|
while (encode_frame(&codec, NULL, -1, 0, writer)) {};
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
fclose(infile);
|
fclose(infile);
|
||||||
printf("Processed %d frames.\n", frame_count);
|
printf("Processed %d frames.\n", frame_count);
|
||||||
|
|
||||||
vpx_img_free(&raw);
|
vpx_img_free(&raw);
|
||||||
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
|
if (vpx_codec_destroy(&codec))
|
||||||
|
die_codec(&codec, "Failed to destroy codec.");
|
||||||
|
|
||||||
vpx_video_writer_close(writer);
|
vpx_video_writer_close(writer);
|
||||||
|
|
||||||
|
|||||||
@@ -66,16 +66,20 @@ void usage_exit(void) {
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_frame_stats(vpx_codec_ctx_t *ctx, const vpx_image_t *img,
|
static int get_frame_stats(vpx_codec_ctx_t *ctx,
|
||||||
vpx_codec_pts_t pts, unsigned int duration,
|
const vpx_image_t *img,
|
||||||
vpx_enc_frame_flags_t flags, unsigned int deadline,
|
vpx_codec_pts_t pts,
|
||||||
|
unsigned int duration,
|
||||||
|
vpx_enc_frame_flags_t flags,
|
||||||
|
unsigned int deadline,
|
||||||
vpx_fixed_buf_t *stats) {
|
vpx_fixed_buf_t *stats) {
|
||||||
int got_pkts = 0;
|
int got_pkts = 0;
|
||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
const vpx_codec_cx_pkt_t *pkt = NULL;
|
const vpx_codec_cx_pkt_t *pkt = NULL;
|
||||||
const vpx_codec_err_t res =
|
const vpx_codec_err_t res = vpx_codec_encode(ctx, img, pts, duration, flags,
|
||||||
vpx_codec_encode(ctx, img, pts, duration, flags, deadline);
|
deadline);
|
||||||
if (res != VPX_CODEC_OK) die_codec(ctx, "Failed to get frame stats.");
|
if (res != VPX_CODEC_OK)
|
||||||
|
die_codec(ctx, "Failed to get frame stats.");
|
||||||
|
|
||||||
while ((pkt = vpx_codec_get_cx_data(ctx, &iter)) != NULL) {
|
while ((pkt = vpx_codec_get_cx_data(ctx, &iter)) != NULL) {
|
||||||
got_pkts = 1;
|
got_pkts = 1;
|
||||||
@@ -92,16 +96,20 @@ static int get_frame_stats(vpx_codec_ctx_t *ctx, const vpx_image_t *img,
|
|||||||
return got_pkts;
|
return got_pkts;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int encode_frame(vpx_codec_ctx_t *ctx, const vpx_image_t *img,
|
static int encode_frame(vpx_codec_ctx_t *ctx,
|
||||||
vpx_codec_pts_t pts, unsigned int duration,
|
const vpx_image_t *img,
|
||||||
vpx_enc_frame_flags_t flags, unsigned int deadline,
|
vpx_codec_pts_t pts,
|
||||||
|
unsigned int duration,
|
||||||
|
vpx_enc_frame_flags_t flags,
|
||||||
|
unsigned int deadline,
|
||||||
VpxVideoWriter *writer) {
|
VpxVideoWriter *writer) {
|
||||||
int got_pkts = 0;
|
int got_pkts = 0;
|
||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
const vpx_codec_cx_pkt_t *pkt = NULL;
|
const vpx_codec_cx_pkt_t *pkt = NULL;
|
||||||
const vpx_codec_err_t res =
|
const vpx_codec_err_t res = vpx_codec_encode(ctx, img, pts, duration, flags,
|
||||||
vpx_codec_encode(ctx, img, pts, duration, flags, deadline);
|
deadline);
|
||||||
if (res != VPX_CODEC_OK) die_codec(ctx, "Failed to encode frame.");
|
if (res != VPX_CODEC_OK)
|
||||||
|
die_codec(ctx, "Failed to encode frame.");
|
||||||
|
|
||||||
while ((pkt = vpx_codec_get_cx_data(ctx, &iter)) != NULL) {
|
while ((pkt = vpx_codec_get_cx_data(ctx, &iter)) != NULL) {
|
||||||
got_pkts = 1;
|
got_pkts = 1;
|
||||||
@@ -120,9 +128,11 @@ static int encode_frame(vpx_codec_ctx_t *ctx, const vpx_image_t *img,
|
|||||||
return got_pkts;
|
return got_pkts;
|
||||||
}
|
}
|
||||||
|
|
||||||
static vpx_fixed_buf_t pass0(vpx_image_t *raw, FILE *infile,
|
static vpx_fixed_buf_t pass0(vpx_image_t *raw,
|
||||||
|
FILE *infile,
|
||||||
const VpxInterface *encoder,
|
const VpxInterface *encoder,
|
||||||
const vpx_codec_enc_cfg_t *cfg, int max_frames) {
|
const vpx_codec_enc_cfg_t *cfg,
|
||||||
|
int max_frames) {
|
||||||
vpx_codec_ctx_t codec;
|
vpx_codec_ctx_t codec;
|
||||||
int frame_count = 0;
|
int frame_count = 0;
|
||||||
vpx_fixed_buf_t stats = {NULL, 0};
|
vpx_fixed_buf_t stats = {NULL, 0};
|
||||||
@@ -135,33 +145,40 @@ static vpx_fixed_buf_t pass0(vpx_image_t *raw, FILE *infile,
|
|||||||
++frame_count;
|
++frame_count;
|
||||||
get_frame_stats(&codec, raw, frame_count, 1, 0, VPX_DL_GOOD_QUALITY,
|
get_frame_stats(&codec, raw, frame_count, 1, 0, VPX_DL_GOOD_QUALITY,
|
||||||
&stats);
|
&stats);
|
||||||
if (max_frames > 0 && frame_count >= max_frames) break;
|
if (max_frames > 0 && frame_count >= max_frames)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush encoder.
|
// Flush encoder.
|
||||||
while (get_frame_stats(&codec, NULL, frame_count, 1, 0, VPX_DL_GOOD_QUALITY,
|
while (get_frame_stats(&codec, NULL, frame_count, 1, 0,
|
||||||
&stats)) {
|
VPX_DL_GOOD_QUALITY, &stats)) {}
|
||||||
}
|
|
||||||
|
|
||||||
printf("Pass 0 complete. Processed %d frames.\n", frame_count);
|
printf("Pass 0 complete. Processed %d frames.\n", frame_count);
|
||||||
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
|
if (vpx_codec_destroy(&codec))
|
||||||
|
die_codec(&codec, "Failed to destroy codec.");
|
||||||
|
|
||||||
return stats;
|
return stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pass1(vpx_image_t *raw, FILE *infile, const char *outfile_name,
|
static void pass1(vpx_image_t *raw,
|
||||||
const VpxInterface *encoder, const vpx_codec_enc_cfg_t *cfg,
|
FILE *infile,
|
||||||
|
const char *outfile_name,
|
||||||
|
const VpxInterface *encoder,
|
||||||
|
const vpx_codec_enc_cfg_t *cfg,
|
||||||
int max_frames) {
|
int max_frames) {
|
||||||
VpxVideoInfo info = { encoder->fourcc,
|
VpxVideoInfo info = {
|
||||||
|
encoder->fourcc,
|
||||||
cfg->g_w,
|
cfg->g_w,
|
||||||
cfg->g_h,
|
cfg->g_h,
|
||||||
{ cfg->g_timebase.num, cfg->g_timebase.den } };
|
{cfg->g_timebase.num, cfg->g_timebase.den}
|
||||||
|
};
|
||||||
VpxVideoWriter *writer = NULL;
|
VpxVideoWriter *writer = NULL;
|
||||||
vpx_codec_ctx_t codec;
|
vpx_codec_ctx_t codec;
|
||||||
int frame_count = 0;
|
int frame_count = 0;
|
||||||
|
|
||||||
writer = vpx_video_writer_open(outfile_name, kContainerIVF, &info);
|
writer = vpx_video_writer_open(outfile_name, kContainerIVF, &info);
|
||||||
if (!writer) die("Failed to open %s for writing", outfile_name);
|
if (!writer)
|
||||||
|
die("Failed to open %s for writing", outfile_name);
|
||||||
|
|
||||||
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), cfg, 0))
|
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), cfg, 0))
|
||||||
die_codec(&codec, "Failed to initialize encoder");
|
die_codec(&codec, "Failed to initialize encoder");
|
||||||
@@ -171,16 +188,17 @@ static void pass1(vpx_image_t *raw, FILE *infile, const char *outfile_name,
|
|||||||
++frame_count;
|
++frame_count;
|
||||||
encode_frame(&codec, raw, frame_count, 1, 0, VPX_DL_GOOD_QUALITY, writer);
|
encode_frame(&codec, raw, frame_count, 1, 0, VPX_DL_GOOD_QUALITY, writer);
|
||||||
|
|
||||||
if (max_frames > 0 && frame_count >= max_frames) break;
|
if (max_frames > 0 && frame_count >= max_frames)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush encoder.
|
// Flush encoder.
|
||||||
while (encode_frame(&codec, NULL, -1, 1, 0, VPX_DL_GOOD_QUALITY, writer)) {
|
while (encode_frame(&codec, NULL, -1, 1, 0, VPX_DL_GOOD_QUALITY, writer)) {}
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
|
if (vpx_codec_destroy(&codec))
|
||||||
|
die_codec(&codec, "Failed to destroy codec.");
|
||||||
|
|
||||||
vpx_video_writer_close(writer);
|
vpx_video_writer_close(writer);
|
||||||
|
|
||||||
@@ -207,15 +225,17 @@ int main(int argc, char **argv) {
|
|||||||
int max_frames = 0;
|
int max_frames = 0;
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc != 7) die("Invalid number of arguments.");
|
if (argc != 7)
|
||||||
|
die("Invalid number of arguments.");
|
||||||
|
|
||||||
max_frames = (int)strtol(argv[6], NULL, 0);
|
max_frames = strtol(argv[6], NULL, 0);
|
||||||
|
|
||||||
encoder = get_vpx_encoder_by_name(codec_arg);
|
encoder = get_vpx_encoder_by_name(codec_arg);
|
||||||
if (!encoder) die("Unsupported codec.");
|
if (!encoder)
|
||||||
|
die("Unsupported codec.");
|
||||||
|
|
||||||
w = (int)strtol(width_arg, NULL, 0);
|
w = strtol(width_arg, NULL, 0);
|
||||||
h = (int)strtol(height_arg, NULL, 0);
|
h = strtol(height_arg, NULL, 0);
|
||||||
|
|
||||||
if (w <= 0 || h <= 0 || (w % 2) != 0 || (h % 2) != 0)
|
if (w <= 0 || h <= 0 || (w % 2) != 0 || (h % 2) != 0)
|
||||||
die("Invalid frame size: %dx%d", w, h);
|
die("Invalid frame size: %dx%d", w, h);
|
||||||
@@ -227,7 +247,8 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
||||||
if (res) die_codec(&codec, "Failed to get default codec config.");
|
if (res)
|
||||||
|
die_codec(&codec, "Failed to get default codec config.");
|
||||||
|
|
||||||
cfg.g_w = w;
|
cfg.g_w = w;
|
||||||
cfg.g_h = h;
|
cfg.g_h = h;
|
||||||
|
|||||||
@@ -1,666 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is an example demonstrating multi-resolution encoding in VP8.
|
|
||||||
* High-resolution input video is down-sampled to lower-resolutions. The
|
|
||||||
* encoder then encodes the video and outputs multiple bitstreams with
|
|
||||||
* different resolutions.
|
|
||||||
*
|
|
||||||
* This test also allows for settings temporal layers for each spatial layer.
|
|
||||||
* Different number of temporal layers per spatial stream may be used.
|
|
||||||
* Currently up to 3 temporal layers per spatial stream (encoder) are supported
|
|
||||||
* in this test.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include "vpx_ports/vpx_timer.h"
|
|
||||||
#include "vpx/vpx_encoder.h"
|
|
||||||
#include "vpx/vp8cx.h"
|
|
||||||
#include "vpx_ports/mem_ops.h"
|
|
||||||
#include "../tools_common.h"
|
|
||||||
#define interface (vpx_codec_vp8_cx())
|
|
||||||
#define fourcc 0x30385056
|
|
||||||
|
|
||||||
void usage_exit(void) { exit(EXIT_FAILURE); }
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The input video frame is downsampled several times to generate a multi-level
|
|
||||||
* hierarchical structure. NUM_ENCODERS is defined as the number of encoding
|
|
||||||
* levels required. For example, if the size of input video is 1280x720,
|
|
||||||
* NUM_ENCODERS is 3, and down-sampling factor is 2, the encoder outputs 3
|
|
||||||
* bitstreams with resolution of 1280x720(level 0), 640x360(level 1), and
|
|
||||||
* 320x180(level 2) respectively.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Number of encoders (spatial resolutions) used in this test. */
|
|
||||||
#define NUM_ENCODERS 3
|
|
||||||
|
|
||||||
/* Maximum number of temporal layers allowed for this test. */
|
|
||||||
#define MAX_NUM_TEMPORAL_LAYERS 3
|
|
||||||
|
|
||||||
/* This example uses the scaler function in libyuv. */
|
|
||||||
#include "third_party/libyuv/include/libyuv/basic_types.h"
|
|
||||||
#include "third_party/libyuv/include/libyuv/scale.h"
|
|
||||||
#include "third_party/libyuv/include/libyuv/cpu_id.h"
|
|
||||||
|
|
||||||
int (*read_frame_p)(FILE *f, vpx_image_t *img);
|
|
||||||
|
|
||||||
static int read_frame(FILE *f, vpx_image_t *img) {
|
|
||||||
size_t nbytes, to_read;
|
|
||||||
int res = 1;
|
|
||||||
|
|
||||||
to_read = img->w * img->h * 3 / 2;
|
|
||||||
nbytes = fread(img->planes[0], 1, to_read, f);
|
|
||||||
if (nbytes != to_read) {
|
|
||||||
res = 0;
|
|
||||||
if (nbytes > 0)
|
|
||||||
printf("Warning: Read partial frame. Check your width & height!\n");
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int read_frame_by_row(FILE *f, vpx_image_t *img) {
|
|
||||||
size_t nbytes, to_read;
|
|
||||||
int res = 1;
|
|
||||||
int plane;
|
|
||||||
|
|
||||||
for (plane = 0; plane < 3; plane++) {
|
|
||||||
unsigned char *ptr;
|
|
||||||
int w = (plane ? (1 + img->d_w) / 2 : img->d_w);
|
|
||||||
int h = (plane ? (1 + img->d_h) / 2 : img->d_h);
|
|
||||||
int r;
|
|
||||||
|
|
||||||
/* Determine the correct plane based on the image format. The for-loop
|
|
||||||
* always counts in Y,U,V order, but this may not match the order of
|
|
||||||
* the data on disk.
|
|
||||||
*/
|
|
||||||
switch (plane) {
|
|
||||||
case 1:
|
|
||||||
ptr = img->planes[img->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_V
|
|
||||||
: VPX_PLANE_U];
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
ptr = img->planes[img->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_U
|
|
||||||
: VPX_PLANE_V];
|
|
||||||
break;
|
|
||||||
default: ptr = img->planes[plane];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (r = 0; r < h; r++) {
|
|
||||||
to_read = w;
|
|
||||||
|
|
||||||
nbytes = fread(ptr, 1, to_read, f);
|
|
||||||
if (nbytes != to_read) {
|
|
||||||
res = 0;
|
|
||||||
if (nbytes > 0)
|
|
||||||
printf("Warning: Read partial frame. Check your width & height!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr += img->stride[plane];
|
|
||||||
}
|
|
||||||
if (!res) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void write_ivf_file_header(FILE *outfile, const vpx_codec_enc_cfg_t *cfg,
|
|
||||||
int frame_cnt) {
|
|
||||||
char header[32];
|
|
||||||
|
|
||||||
if (cfg->g_pass != VPX_RC_ONE_PASS && cfg->g_pass != VPX_RC_LAST_PASS) return;
|
|
||||||
header[0] = 'D';
|
|
||||||
header[1] = 'K';
|
|
||||||
header[2] = 'I';
|
|
||||||
header[3] = 'F';
|
|
||||||
mem_put_le16(header + 4, 0); /* version */
|
|
||||||
mem_put_le16(header + 6, 32); /* headersize */
|
|
||||||
mem_put_le32(header + 8, fourcc); /* headersize */
|
|
||||||
mem_put_le16(header + 12, cfg->g_w); /* width */
|
|
||||||
mem_put_le16(header + 14, cfg->g_h); /* height */
|
|
||||||
mem_put_le32(header + 16, cfg->g_timebase.den); /* rate */
|
|
||||||
mem_put_le32(header + 20, cfg->g_timebase.num); /* scale */
|
|
||||||
mem_put_le32(header + 24, frame_cnt); /* length */
|
|
||||||
mem_put_le32(header + 28, 0); /* unused */
|
|
||||||
|
|
||||||
(void)fwrite(header, 1, 32, outfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void write_ivf_frame_header(FILE *outfile,
|
|
||||||
const vpx_codec_cx_pkt_t *pkt) {
|
|
||||||
char header[12];
|
|
||||||
vpx_codec_pts_t pts;
|
|
||||||
|
|
||||||
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return;
|
|
||||||
|
|
||||||
pts = pkt->data.frame.pts;
|
|
||||||
mem_put_le32(header, (int)pkt->data.frame.sz);
|
|
||||||
mem_put_le32(header + 4, pts & 0xFFFFFFFF);
|
|
||||||
mem_put_le32(header + 8, pts >> 32);
|
|
||||||
|
|
||||||
(void)fwrite(header, 1, 12, outfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Temporal scaling parameters */
|
|
||||||
/* This sets all the temporal layer parameters given |num_temporal_layers|,
|
|
||||||
* including the target bit allocation across temporal layers. Bit allocation
|
|
||||||
* parameters will be passed in as user parameters in another version.
|
|
||||||
*/
|
|
||||||
static void set_temporal_layer_pattern(int num_temporal_layers,
|
|
||||||
vpx_codec_enc_cfg_t *cfg, int bitrate,
|
|
||||||
int *layer_flags) {
|
|
||||||
assert(num_temporal_layers <= MAX_NUM_TEMPORAL_LAYERS);
|
|
||||||
switch (num_temporal_layers) {
|
|
||||||
case 1: {
|
|
||||||
/* 1-layer */
|
|
||||||
cfg->ts_number_layers = 1;
|
|
||||||
cfg->ts_periodicity = 1;
|
|
||||||
cfg->ts_rate_decimator[0] = 1;
|
|
||||||
cfg->ts_layer_id[0] = 0;
|
|
||||||
cfg->ts_target_bitrate[0] = bitrate;
|
|
||||||
|
|
||||||
// Update L only.
|
|
||||||
layer_flags[0] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 2: {
|
|
||||||
/* 2-layers, with sync point at first frame of layer 1. */
|
|
||||||
cfg->ts_number_layers = 2;
|
|
||||||
cfg->ts_periodicity = 2;
|
|
||||||
cfg->ts_rate_decimator[0] = 2;
|
|
||||||
cfg->ts_rate_decimator[1] = 1;
|
|
||||||
cfg->ts_layer_id[0] = 0;
|
|
||||||
cfg->ts_layer_id[1] = 1;
|
|
||||||
// Use 60/40 bit allocation as example.
|
|
||||||
cfg->ts_target_bitrate[0] = (int)(0.6f * bitrate);
|
|
||||||
cfg->ts_target_bitrate[1] = bitrate;
|
|
||||||
|
|
||||||
/* 0=L, 1=GF */
|
|
||||||
// ARF is used as predictor for all frames, and is only updated on
|
|
||||||
// key frame. Sync point every 8 frames.
|
|
||||||
|
|
||||||
// Layer 0: predict from L and ARF, update L and G.
|
|
||||||
layer_flags[0] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
|
|
||||||
// Layer 1: sync point: predict from L and ARF, and update G.
|
|
||||||
layer_flags[1] =
|
|
||||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
|
|
||||||
// Layer 0, predict from L and ARF, update L.
|
|
||||||
layer_flags[2] =
|
|
||||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
|
|
||||||
// Layer 1: predict from L, G and ARF, and update G.
|
|
||||||
layer_flags[3] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
|
||||||
VP8_EFLAG_NO_UPD_ENTROPY;
|
|
||||||
|
|
||||||
// Layer 0
|
|
||||||
layer_flags[4] = layer_flags[2];
|
|
||||||
|
|
||||||
// Layer 1
|
|
||||||
layer_flags[5] = layer_flags[3];
|
|
||||||
|
|
||||||
// Layer 0
|
|
||||||
layer_flags[6] = layer_flags[4];
|
|
||||||
|
|
||||||
// Layer 1
|
|
||||||
layer_flags[7] = layer_flags[5];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
default: {
|
|
||||||
// 3-layers structure where ARF is used as predictor for all frames,
|
|
||||||
// and is only updated on key frame.
|
|
||||||
// Sync points for layer 1 and 2 every 8 frames.
|
|
||||||
cfg->ts_number_layers = 3;
|
|
||||||
cfg->ts_periodicity = 4;
|
|
||||||
cfg->ts_rate_decimator[0] = 4;
|
|
||||||
cfg->ts_rate_decimator[1] = 2;
|
|
||||||
cfg->ts_rate_decimator[2] = 1;
|
|
||||||
cfg->ts_layer_id[0] = 0;
|
|
||||||
cfg->ts_layer_id[1] = 2;
|
|
||||||
cfg->ts_layer_id[2] = 1;
|
|
||||||
cfg->ts_layer_id[3] = 2;
|
|
||||||
// Use 45/20/35 bit allocation as example.
|
|
||||||
cfg->ts_target_bitrate[0] = (int)(0.45f * bitrate);
|
|
||||||
cfg->ts_target_bitrate[1] = (int)(0.65f * bitrate);
|
|
||||||
cfg->ts_target_bitrate[2] = bitrate;
|
|
||||||
|
|
||||||
/* 0=L, 1=GF, 2=ARF */
|
|
||||||
|
|
||||||
// Layer 0: predict from L and ARF; update L and G.
|
|
||||||
layer_flags[0] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
|
|
||||||
|
|
||||||
// Layer 2: sync point: predict from L and ARF; update none.
|
|
||||||
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
|
|
||||||
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
|
||||||
VP8_EFLAG_NO_UPD_ENTROPY;
|
|
||||||
|
|
||||||
// Layer 1: sync point: predict from L and ARF; update G.
|
|
||||||
layer_flags[2] =
|
|
||||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
|
||||||
|
|
||||||
// Layer 2: predict from L, G, ARF; update none.
|
|
||||||
layer_flags[3] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
|
|
||||||
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY;
|
|
||||||
|
|
||||||
// Layer 0: predict from L and ARF; update L.
|
|
||||||
layer_flags[4] =
|
|
||||||
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
|
|
||||||
|
|
||||||
// Layer 2: predict from L, G, ARF; update none.
|
|
||||||
layer_flags[5] = layer_flags[3];
|
|
||||||
|
|
||||||
// Layer 1: predict from L, G, ARF; update G.
|
|
||||||
layer_flags[6] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
|
||||||
|
|
||||||
// Layer 2: predict from L, G, ARF; update none.
|
|
||||||
layer_flags[7] = layer_flags[3];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The periodicity of the pattern given the number of temporal layers. */
|
|
||||||
static int periodicity_to_num_layers[MAX_NUM_TEMPORAL_LAYERS] = { 1, 8, 8 };
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
FILE *infile, *outfile[NUM_ENCODERS];
|
|
||||||
FILE *downsampled_input[NUM_ENCODERS - 1];
|
|
||||||
char filename[50];
|
|
||||||
vpx_codec_ctx_t codec[NUM_ENCODERS];
|
|
||||||
vpx_codec_enc_cfg_t cfg[NUM_ENCODERS];
|
|
||||||
int frame_cnt = 0;
|
|
||||||
vpx_image_t raw[NUM_ENCODERS];
|
|
||||||
vpx_codec_err_t res[NUM_ENCODERS];
|
|
||||||
|
|
||||||
int i;
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
int length_frame;
|
|
||||||
int frame_avail;
|
|
||||||
int got_data;
|
|
||||||
int flags = 0;
|
|
||||||
int layer_id = 0;
|
|
||||||
|
|
||||||
int layer_flags[VPX_TS_MAX_PERIODICITY * NUM_ENCODERS] = { 0 };
|
|
||||||
int flag_periodicity;
|
|
||||||
|
|
||||||
/*Currently, only realtime mode is supported in multi-resolution encoding.*/
|
|
||||||
int arg_deadline = VPX_DL_REALTIME;
|
|
||||||
|
|
||||||
/* Set show_psnr to 1/0 to show/not show PSNR. Choose show_psnr=0 if you
|
|
||||||
don't need to know PSNR, which will skip PSNR calculation and save
|
|
||||||
encoding time. */
|
|
||||||
int show_psnr = 0;
|
|
||||||
int key_frame_insert = 0;
|
|
||||||
uint64_t psnr_sse_total[NUM_ENCODERS] = { 0 };
|
|
||||||
uint64_t psnr_samples_total[NUM_ENCODERS] = { 0 };
|
|
||||||
double psnr_totals[NUM_ENCODERS][4] = { { 0, 0 } };
|
|
||||||
int psnr_count[NUM_ENCODERS] = { 0 };
|
|
||||||
|
|
||||||
int64_t cx_time = 0;
|
|
||||||
|
|
||||||
/* Set the required target bitrates for each resolution level.
|
|
||||||
* If target bitrate for highest-resolution level is set to 0,
|
|
||||||
* (i.e. target_bitrate[0]=0), we skip encoding at that level.
|
|
||||||
*/
|
|
||||||
unsigned int target_bitrate[NUM_ENCODERS] = { 1000, 500, 100 };
|
|
||||||
|
|
||||||
/* Enter the frame rate of the input video */
|
|
||||||
int framerate = 30;
|
|
||||||
|
|
||||||
/* Set down-sampling factor for each resolution level.
|
|
||||||
dsf[0] controls down sampling from level 0 to level 1;
|
|
||||||
dsf[1] controls down sampling from level 1 to level 2;
|
|
||||||
dsf[2] is not used. */
|
|
||||||
vpx_rational_t dsf[NUM_ENCODERS] = { { 2, 1 }, { 2, 1 }, { 1, 1 } };
|
|
||||||
|
|
||||||
/* Set the number of temporal layers for each encoder/resolution level,
|
|
||||||
* starting from highest resoln down to lowest resoln. */
|
|
||||||
unsigned int num_temporal_layers[NUM_ENCODERS] = { 3, 3, 3 };
|
|
||||||
|
|
||||||
if (argc != (7 + 3 * NUM_ENCODERS))
|
|
||||||
die("Usage: %s <width> <height> <frame_rate> <infile> <outfile(s)> "
|
|
||||||
"<rate_encoder(s)> <temporal_layer(s)> <key_frame_insert> <output "
|
|
||||||
"psnr?> \n",
|
|
||||||
argv[0]);
|
|
||||||
|
|
||||||
printf("Using %s\n", vpx_codec_iface_name(interface));
|
|
||||||
|
|
||||||
width = (int)strtol(argv[1], NULL, 0);
|
|
||||||
height = (int)strtol(argv[2], NULL, 0);
|
|
||||||
framerate = (int)strtol(argv[3], NULL, 0);
|
|
||||||
|
|
||||||
if (width < 16 || width % 2 || height < 16 || height % 2)
|
|
||||||
die("Invalid resolution: %ldx%ld", width, height);
|
|
||||||
|
|
||||||
/* Open input video file for encoding */
|
|
||||||
if (!(infile = fopen(argv[4], "rb")))
|
|
||||||
die("Failed to open %s for reading", argv[4]);
|
|
||||||
|
|
||||||
/* Open output file for each encoder to output bitstreams */
|
|
||||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
|
||||||
if (!target_bitrate[i]) {
|
|
||||||
outfile[i] = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(outfile[i] = fopen(argv[i + 5], "wb")))
|
|
||||||
die("Failed to open %s for writing", argv[i + 4]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bitrates per spatial layer: overwrite default rates above.
|
|
||||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
|
||||||
target_bitrate[i] = (int)strtol(argv[NUM_ENCODERS + 5 + i], NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Temporal layers per spatial layers: overwrite default settings above.
|
|
||||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
|
||||||
num_temporal_layers[i] =
|
|
||||||
(int)strtol(argv[2 * NUM_ENCODERS + 5 + i], NULL, 0);
|
|
||||||
if (num_temporal_layers[i] < 1 || num_temporal_layers[i] > 3)
|
|
||||||
die("Invalid temporal layers: %d, Must be 1, 2, or 3. \n",
|
|
||||||
num_temporal_layers);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open file to write out each spatially downsampled input stream. */
|
|
||||||
for (i = 0; i < NUM_ENCODERS - 1; i++) {
|
|
||||||
// Highest resoln is encoder 0.
|
|
||||||
if (sprintf(filename, "ds%d.yuv", NUM_ENCODERS - i) < 0) {
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
downsampled_input[i] = fopen(filename, "wb");
|
|
||||||
}
|
|
||||||
|
|
||||||
key_frame_insert = (int)strtol(argv[3 * NUM_ENCODERS + 5], NULL, 0);
|
|
||||||
|
|
||||||
show_psnr = (int)strtol(argv[3 * NUM_ENCODERS + 6], NULL, 0);
|
|
||||||
|
|
||||||
/* Populate default encoder configuration */
|
|
||||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
|
||||||
res[i] = vpx_codec_enc_config_default(interface, &cfg[i], 0);
|
|
||||||
if (res[i]) {
|
|
||||||
printf("Failed to get config: %s\n", vpx_codec_err_to_string(res[i]));
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update the default configuration according to needs of the application.
|
|
||||||
*/
|
|
||||||
/* Highest-resolution encoder settings */
|
|
||||||
cfg[0].g_w = width;
|
|
||||||
cfg[0].g_h = height;
|
|
||||||
cfg[0].rc_dropframe_thresh = 0;
|
|
||||||
cfg[0].rc_end_usage = VPX_CBR;
|
|
||||||
cfg[0].rc_resize_allowed = 0;
|
|
||||||
cfg[0].rc_min_quantizer = 2;
|
|
||||||
cfg[0].rc_max_quantizer = 56;
|
|
||||||
cfg[0].rc_undershoot_pct = 100;
|
|
||||||
cfg[0].rc_overshoot_pct = 15;
|
|
||||||
cfg[0].rc_buf_initial_sz = 500;
|
|
||||||
cfg[0].rc_buf_optimal_sz = 600;
|
|
||||||
cfg[0].rc_buf_sz = 1000;
|
|
||||||
cfg[0].g_error_resilient = 1; /* Enable error resilient mode */
|
|
||||||
cfg[0].g_lag_in_frames = 0;
|
|
||||||
|
|
||||||
/* Disable automatic keyframe placement */
|
|
||||||
/* Note: These 3 settings are copied to all levels. But, except the lowest
|
|
||||||
* resolution level, all other levels are set to VPX_KF_DISABLED internally.
|
|
||||||
*/
|
|
||||||
cfg[0].kf_mode = VPX_KF_AUTO;
|
|
||||||
cfg[0].kf_min_dist = 3000;
|
|
||||||
cfg[0].kf_max_dist = 3000;
|
|
||||||
|
|
||||||
cfg[0].rc_target_bitrate = target_bitrate[0]; /* Set target bitrate */
|
|
||||||
cfg[0].g_timebase.num = 1; /* Set fps */
|
|
||||||
cfg[0].g_timebase.den = framerate;
|
|
||||||
|
|
||||||
/* Other-resolution encoder settings */
|
|
||||||
for (i = 1; i < NUM_ENCODERS; i++) {
|
|
||||||
memcpy(&cfg[i], &cfg[0], sizeof(vpx_codec_enc_cfg_t));
|
|
||||||
|
|
||||||
cfg[i].rc_target_bitrate = target_bitrate[i];
|
|
||||||
|
|
||||||
/* Note: Width & height of other-resolution encoders are calculated
|
|
||||||
* from the highest-resolution encoder's size and the corresponding
|
|
||||||
* down_sampling_factor.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
unsigned int iw = cfg[i - 1].g_w * dsf[i - 1].den + dsf[i - 1].num - 1;
|
|
||||||
unsigned int ih = cfg[i - 1].g_h * dsf[i - 1].den + dsf[i - 1].num - 1;
|
|
||||||
cfg[i].g_w = iw / dsf[i - 1].num;
|
|
||||||
cfg[i].g_h = ih / dsf[i - 1].num;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make width & height to be multiplier of 2. */
|
|
||||||
// Should support odd size ???
|
|
||||||
if ((cfg[i].g_w) % 2) cfg[i].g_w++;
|
|
||||||
if ((cfg[i].g_h) % 2) cfg[i].g_h++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the number of threads per encode/spatial layer.
|
|
||||||
// (1, 1, 1) means no encoder threading.
|
|
||||||
cfg[0].g_threads = 1;
|
|
||||||
cfg[1].g_threads = 1;
|
|
||||||
cfg[2].g_threads = 1;
|
|
||||||
|
|
||||||
/* Allocate image for each encoder */
|
|
||||||
for (i = 0; i < NUM_ENCODERS; i++)
|
|
||||||
if (!vpx_img_alloc(&raw[i], VPX_IMG_FMT_I420, cfg[i].g_w, cfg[i].g_h, 32))
|
|
||||||
die("Failed to allocate image", cfg[i].g_w, cfg[i].g_h);
|
|
||||||
|
|
||||||
if (raw[0].stride[VPX_PLANE_Y] == (int)raw[0].d_w)
|
|
||||||
read_frame_p = read_frame;
|
|
||||||
else
|
|
||||||
read_frame_p = read_frame_by_row;
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_ENCODERS; i++)
|
|
||||||
if (outfile[i]) write_ivf_file_header(outfile[i], &cfg[i], 0);
|
|
||||||
|
|
||||||
/* Temporal layers settings */
|
|
||||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
|
||||||
set_temporal_layer_pattern(num_temporal_layers[i], &cfg[i],
|
|
||||||
cfg[i].rc_target_bitrate,
|
|
||||||
&layer_flags[i * VPX_TS_MAX_PERIODICITY]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize multi-encoder */
|
|
||||||
if (vpx_codec_enc_init_multi(&codec[0], interface, &cfg[0], NUM_ENCODERS,
|
|
||||||
(show_psnr ? VPX_CODEC_USE_PSNR : 0), &dsf[0]))
|
|
||||||
die_codec(&codec[0], "Failed to initialize encoder");
|
|
||||||
|
|
||||||
/* The extra encoding configuration parameters can be set as follows. */
|
|
||||||
/* Set encoding speed */
|
|
||||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
|
||||||
int speed = -6;
|
|
||||||
/* Lower speed for the lowest resolution. */
|
|
||||||
if (i == NUM_ENCODERS - 1) speed = -4;
|
|
||||||
if (vpx_codec_control(&codec[i], VP8E_SET_CPUUSED, speed))
|
|
||||||
die_codec(&codec[i], "Failed to set cpu_used");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set static threshold = 1 for all encoders */
|
|
||||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
|
||||||
if (vpx_codec_control(&codec[i], VP8E_SET_STATIC_THRESHOLD, 1))
|
|
||||||
die_codec(&codec[i], "Failed to set static threshold");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set NOISE_SENSITIVITY to do TEMPORAL_DENOISING */
|
|
||||||
/* Enable denoising for the highest-resolution encoder. */
|
|
||||||
if (vpx_codec_control(&codec[0], VP8E_SET_NOISE_SENSITIVITY, 1))
|
|
||||||
die_codec(&codec[0], "Failed to set noise_sensitivity");
|
|
||||||
if (vpx_codec_control(&codec[1], VP8E_SET_NOISE_SENSITIVITY, 1))
|
|
||||||
die_codec(&codec[1], "Failed to set noise_sensitivity");
|
|
||||||
for (i = 2; i < NUM_ENCODERS; i++) {
|
|
||||||
if (vpx_codec_control(&codec[i], VP8E_SET_NOISE_SENSITIVITY, 0))
|
|
||||||
die_codec(&codec[i], "Failed to set noise_sensitivity");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the number of token partitions */
|
|
||||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
|
||||||
if (vpx_codec_control(&codec[i], VP8E_SET_TOKEN_PARTITIONS, 1))
|
|
||||||
die_codec(&codec[i], "Failed to set static threshold");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the max intra target bitrate */
|
|
||||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
|
||||||
unsigned int max_intra_size_pct =
|
|
||||||
(int)(((double)cfg[0].rc_buf_optimal_sz * 0.5) * framerate / 10);
|
|
||||||
if (vpx_codec_control(&codec[i], VP8E_SET_MAX_INTRA_BITRATE_PCT,
|
|
||||||
max_intra_size_pct))
|
|
||||||
die_codec(&codec[i], "Failed to set static threshold");
|
|
||||||
// printf("%d %d \n",i,max_intra_size_pct);
|
|
||||||
}
|
|
||||||
|
|
||||||
frame_avail = 1;
|
|
||||||
got_data = 0;
|
|
||||||
|
|
||||||
while (frame_avail || got_data) {
|
|
||||||
struct vpx_usec_timer timer;
|
|
||||||
vpx_codec_iter_t iter[NUM_ENCODERS] = { NULL };
|
|
||||||
const vpx_codec_cx_pkt_t *pkt[NUM_ENCODERS];
|
|
||||||
|
|
||||||
flags = 0;
|
|
||||||
frame_avail = read_frame_p(infile, &raw[0]);
|
|
||||||
|
|
||||||
if (frame_avail) {
|
|
||||||
for (i = 1; i < NUM_ENCODERS; i++) {
|
|
||||||
/*Scale the image down a number of times by downsampling factor*/
|
|
||||||
/* FilterMode 1 or 2 give better psnr than FilterMode 0. */
|
|
||||||
I420Scale(
|
|
||||||
raw[i - 1].planes[VPX_PLANE_Y], raw[i - 1].stride[VPX_PLANE_Y],
|
|
||||||
raw[i - 1].planes[VPX_PLANE_U], raw[i - 1].stride[VPX_PLANE_U],
|
|
||||||
raw[i - 1].planes[VPX_PLANE_V], raw[i - 1].stride[VPX_PLANE_V],
|
|
||||||
raw[i - 1].d_w, raw[i - 1].d_h, raw[i].planes[VPX_PLANE_Y],
|
|
||||||
raw[i].stride[VPX_PLANE_Y], raw[i].planes[VPX_PLANE_U],
|
|
||||||
raw[i].stride[VPX_PLANE_U], raw[i].planes[VPX_PLANE_V],
|
|
||||||
raw[i].stride[VPX_PLANE_V], raw[i].d_w, raw[i].d_h, 1);
|
|
||||||
/* Write out down-sampled input. */
|
|
||||||
length_frame = cfg[i].g_w * cfg[i].g_h * 3 / 2;
|
|
||||||
if (fwrite(raw[i].planes[0], 1, length_frame,
|
|
||||||
downsampled_input[NUM_ENCODERS - i - 1]) !=
|
|
||||||
(unsigned int)length_frame) {
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the flags (reference and update) for all the encoders.*/
|
|
||||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
|
||||||
layer_id = cfg[i].ts_layer_id[frame_cnt % cfg[i].ts_periodicity];
|
|
||||||
flags = 0;
|
|
||||||
flag_periodicity = periodicity_to_num_layers[num_temporal_layers[i] - 1];
|
|
||||||
flags = layer_flags[i * VPX_TS_MAX_PERIODICITY +
|
|
||||||
frame_cnt % flag_periodicity];
|
|
||||||
// Key frame flag for first frame.
|
|
||||||
if (frame_cnt == 0) {
|
|
||||||
flags |= VPX_EFLAG_FORCE_KF;
|
|
||||||
}
|
|
||||||
if (frame_cnt > 0 && frame_cnt == key_frame_insert) {
|
|
||||||
flags = VPX_EFLAG_FORCE_KF;
|
|
||||||
}
|
|
||||||
|
|
||||||
vpx_codec_control(&codec[i], VP8E_SET_FRAME_FLAGS, flags);
|
|
||||||
vpx_codec_control(&codec[i], VP8E_SET_TEMPORAL_LAYER_ID, layer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Encode each frame at multi-levels */
|
|
||||||
/* Note the flags must be set to 0 in the encode call if they are set
|
|
||||||
for each frame with the vpx_codec_control(), as done above. */
|
|
||||||
vpx_usec_timer_start(&timer);
|
|
||||||
if (vpx_codec_encode(&codec[0], frame_avail ? &raw[0] : NULL, frame_cnt, 1,
|
|
||||||
0, arg_deadline)) {
|
|
||||||
die_codec(&codec[0], "Failed to encode frame");
|
|
||||||
}
|
|
||||||
vpx_usec_timer_mark(&timer);
|
|
||||||
cx_time += vpx_usec_timer_elapsed(&timer);
|
|
||||||
|
|
||||||
for (i = NUM_ENCODERS - 1; i >= 0; i--) {
|
|
||||||
got_data = 0;
|
|
||||||
while ((pkt[i] = vpx_codec_get_cx_data(&codec[i], &iter[i]))) {
|
|
||||||
got_data = 1;
|
|
||||||
switch (pkt[i]->kind) {
|
|
||||||
case VPX_CODEC_CX_FRAME_PKT:
|
|
||||||
write_ivf_frame_header(outfile[i], pkt[i]);
|
|
||||||
(void)fwrite(pkt[i]->data.frame.buf, 1, pkt[i]->data.frame.sz,
|
|
||||||
outfile[i]);
|
|
||||||
break;
|
|
||||||
case VPX_CODEC_PSNR_PKT:
|
|
||||||
if (show_psnr) {
|
|
||||||
int j;
|
|
||||||
|
|
||||||
psnr_sse_total[i] += pkt[i]->data.psnr.sse[0];
|
|
||||||
psnr_samples_total[i] += pkt[i]->data.psnr.samples[0];
|
|
||||||
for (j = 0; j < 4; j++) {
|
|
||||||
psnr_totals[i][j] += pkt[i]->data.psnr.psnr[j];
|
|
||||||
}
|
|
||||||
psnr_count[i]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
frame_cnt++;
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
|
|
||||||
frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000),
|
|
||||||
1000000 * (double)frame_cnt / (double)cx_time);
|
|
||||||
|
|
||||||
fclose(infile);
|
|
||||||
|
|
||||||
printf("Processed %ld frames.\n", (long int)frame_cnt - 1);
|
|
||||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
|
||||||
/* Calculate PSNR and print it out */
|
|
||||||
if ((show_psnr) && (psnr_count[i] > 0)) {
|
|
||||||
int j;
|
|
||||||
double ovpsnr =
|
|
||||||
sse_to_psnr(psnr_samples_total[i], 255.0, psnr_sse_total[i]);
|
|
||||||
|
|
||||||
fprintf(stderr, "\n ENC%d PSNR (Overall/Avg/Y/U/V)", i);
|
|
||||||
|
|
||||||
fprintf(stderr, " %.3lf", ovpsnr);
|
|
||||||
for (j = 0; j < 4; j++) {
|
|
||||||
fprintf(stderr, " %.3lf", psnr_totals[i][j] / psnr_count[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vpx_codec_destroy(&codec[i]))
|
|
||||||
die_codec(&codec[i], "Failed to destroy codec");
|
|
||||||
|
|
||||||
vpx_img_free(&raw[i]);
|
|
||||||
|
|
||||||
if (!outfile[i]) continue;
|
|
||||||
|
|
||||||
/* Try to rewrite the file header with the actual frame count */
|
|
||||||
if (!fseek(outfile[i], 0, SEEK_SET))
|
|
||||||
write_ivf_file_header(outfile[i], &cfg[i], frame_cnt - 1);
|
|
||||||
fclose(outfile[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// VP8 Set Reference Frame
|
// VP8 Set Reference Frame
|
||||||
// =======================
|
// =======================
|
||||||
//
|
//
|
||||||
@@ -51,7 +52,6 @@
|
|||||||
|
|
||||||
#include "vpx/vp8cx.h"
|
#include "vpx/vp8cx.h"
|
||||||
#include "vpx/vpx_encoder.h"
|
#include "vpx/vpx_encoder.h"
|
||||||
#include "vp8/common/common.h"
|
|
||||||
|
|
||||||
#include "../tools_common.h"
|
#include "../tools_common.h"
|
||||||
#include "../video_writer.h"
|
#include "../video_writer.h"
|
||||||
@@ -64,21 +64,25 @@ void usage_exit(void) {
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img,
|
static int encode_frame(vpx_codec_ctx_t *codec,
|
||||||
int frame_index, VpxVideoWriter *writer) {
|
vpx_image_t *img,
|
||||||
|
int frame_index,
|
||||||
|
VpxVideoWriter *writer) {
|
||||||
int got_pkts = 0;
|
int got_pkts = 0;
|
||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
const vpx_codec_cx_pkt_t *pkt = NULL;
|
const vpx_codec_cx_pkt_t *pkt = NULL;
|
||||||
const vpx_codec_err_t res =
|
const vpx_codec_err_t res = vpx_codec_encode(codec, img, frame_index, 1, 0,
|
||||||
vpx_codec_encode(codec, img, frame_index, 1, 0, VPX_DL_GOOD_QUALITY);
|
VPX_DL_GOOD_QUALITY);
|
||||||
if (res != VPX_CODEC_OK) die_codec(codec, "Failed to encode frame");
|
if (res != VPX_CODEC_OK)
|
||||||
|
die_codec(codec, "Failed to encode frame");
|
||||||
|
|
||||||
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
|
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
|
||||||
got_pkts = 1;
|
got_pkts = 1;
|
||||||
|
|
||||||
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
||||||
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
||||||
if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf,
|
if (!vpx_video_writer_write_frame(writer,
|
||||||
|
pkt->data.frame.buf,
|
||||||
pkt->data.frame.sz,
|
pkt->data.frame.sz,
|
||||||
pkt->data.frame.pts)) {
|
pkt->data.frame.pts)) {
|
||||||
die_codec(codec, "Failed to write compressed frame");
|
die_codec(codec, "Failed to write compressed frame");
|
||||||
@@ -94,41 +98,42 @@ static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img,
|
|||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
FILE *infile = NULL;
|
FILE *infile = NULL;
|
||||||
vpx_codec_ctx_t codec;
|
vpx_codec_ctx_t codec = {0};
|
||||||
vpx_codec_enc_cfg_t cfg;
|
vpx_codec_enc_cfg_t cfg = {0};
|
||||||
int frame_count = 0;
|
int frame_count = 0;
|
||||||
vpx_image_t raw;
|
vpx_image_t raw;
|
||||||
vpx_codec_err_t res;
|
vpx_codec_err_t res;
|
||||||
VpxVideoInfo info;
|
VpxVideoInfo info = {0};
|
||||||
VpxVideoWriter *writer = NULL;
|
VpxVideoWriter *writer = NULL;
|
||||||
const VpxInterface *encoder = NULL;
|
const VpxInterface *encoder = NULL;
|
||||||
int update_frame_num = 0;
|
int update_frame_num = 0;
|
||||||
const int fps = 30; // TODO(dkovalev) add command line argument
|
const int fps = 30; // TODO(dkovalev) add command line argument
|
||||||
const int bitrate = 200; // kbit/s TODO(dkovalev) add command line argument
|
const int bitrate = 200; // kbit/s TODO(dkovalev) add command line argument
|
||||||
|
|
||||||
vp8_zero(codec);
|
|
||||||
vp8_zero(cfg);
|
|
||||||
vp8_zero(info);
|
|
||||||
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc != 6) die("Invalid number of arguments");
|
if (argc != 6)
|
||||||
|
die("Invalid number of arguments");
|
||||||
|
|
||||||
// TODO(dkovalev): add vp9 support and rename the file accordingly
|
// TODO(dkovalev): add vp9 support and rename the file accordingly
|
||||||
encoder = get_vpx_encoder_by_name("vp8");
|
encoder = get_vpx_encoder_by_name("vp8");
|
||||||
if (!encoder) die("Unsupported codec.");
|
if (!encoder)
|
||||||
|
die("Unsupported codec.");
|
||||||
|
|
||||||
update_frame_num = atoi(argv[5]);
|
update_frame_num = atoi(argv[5]);
|
||||||
if (!update_frame_num) die("Couldn't parse frame number '%s'\n", argv[5]);
|
if (!update_frame_num)
|
||||||
|
die("Couldn't parse frame number '%s'\n", argv[5]);
|
||||||
|
|
||||||
info.codec_fourcc = encoder->fourcc;
|
info.codec_fourcc = encoder->fourcc;
|
||||||
info.frame_width = (int)strtol(argv[1], NULL, 0);
|
info.frame_width = strtol(argv[1], NULL, 0);
|
||||||
info.frame_height = (int)strtol(argv[2], NULL, 0);
|
info.frame_height = strtol(argv[2], NULL, 0);
|
||||||
info.time_base.numerator = 1;
|
info.time_base.numerator = 1;
|
||||||
info.time_base.denominator = fps;
|
info.time_base.denominator = fps;
|
||||||
|
|
||||||
if (info.frame_width <= 0 || info.frame_height <= 0 ||
|
if (info.frame_width <= 0 ||
|
||||||
(info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
|
info.frame_height <= 0 ||
|
||||||
|
(info.frame_width % 2) != 0 ||
|
||||||
|
(info.frame_height % 2) != 0) {
|
||||||
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +145,8 @@ int main(int argc, char **argv) {
|
|||||||
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
||||||
|
|
||||||
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
||||||
if (res) die_codec(&codec, "Failed to get default codec config.");
|
if (res)
|
||||||
|
die_codec(&codec, "Failed to get default codec config.");
|
||||||
|
|
||||||
cfg.g_w = info.frame_width;
|
cfg.g_w = info.frame_width;
|
||||||
cfg.g_h = info.frame_height;
|
cfg.g_h = info.frame_height;
|
||||||
@@ -149,7 +155,8 @@ int main(int argc, char **argv) {
|
|||||||
cfg.rc_target_bitrate = bitrate;
|
cfg.rc_target_bitrate = bitrate;
|
||||||
|
|
||||||
writer = vpx_video_writer_open(argv[4], kContainerIVF, &info);
|
writer = vpx_video_writer_open(argv[4], kContainerIVF, &info);
|
||||||
if (!writer) die("Failed to open %s for writing.", argv[4]);
|
if (!writer)
|
||||||
|
die("Failed to open %s for writing.", argv[4]);
|
||||||
|
|
||||||
if (!(infile = fopen(argv[3], "rb")))
|
if (!(infile = fopen(argv[3], "rb")))
|
||||||
die("Failed to open %s for reading.", argv[3]);
|
die("Failed to open %s for reading.", argv[3]);
|
||||||
@@ -171,15 +178,15 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Flush encoder.
|
// Flush encoder.
|
||||||
while (encode_frame(&codec, NULL, -1, writer)) {
|
while (encode_frame(&codec, NULL, -1, writer)) {}
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
fclose(infile);
|
fclose(infile);
|
||||||
printf("Processed %d frames.\n", frame_count);
|
printf("Processed %d frames.\n", frame_count);
|
||||||
|
|
||||||
vpx_img_free(&raw);
|
vpx_img_free(&raw);
|
||||||
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
|
if (vpx_codec_destroy(&codec))
|
||||||
|
die_codec(&codec, "Failed to destroy codec.");
|
||||||
|
|
||||||
vpx_video_writer_close(writer);
|
vpx_video_writer_close(writer);
|
||||||
|
|
||||||
|
|||||||
@@ -1,925 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is an example demonstrating how to implement a multi-layer
|
|
||||||
* VP9 encoding scheme based on spatial scalability for video applications
|
|
||||||
* that benefit from a scalable bitstream.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "../args.h"
|
|
||||||
#include "../tools_common.h"
|
|
||||||
#include "../video_writer.h"
|
|
||||||
|
|
||||||
#include "../vpx_ports/vpx_timer.h"
|
|
||||||
#include "vpx/svc_context.h"
|
|
||||||
#include "vpx/vp8cx.h"
|
|
||||||
#include "vpx/vpx_encoder.h"
|
|
||||||
#include "../vpxstats.h"
|
|
||||||
#include "vp9/encoder/vp9_encoder.h"
|
|
||||||
#define OUTPUT_RC_STATS 1
|
|
||||||
|
|
||||||
static const arg_def_t skip_frames_arg =
|
|
||||||
ARG_DEF("s", "skip-frames", 1, "input frames to skip");
|
|
||||||
static const arg_def_t frames_arg =
|
|
||||||
ARG_DEF("f", "frames", 1, "number of frames to encode");
|
|
||||||
static const arg_def_t threads_arg =
|
|
||||||
ARG_DEF("th", "threads", 1, "number of threads to use");
|
|
||||||
#if OUTPUT_RC_STATS
|
|
||||||
static const arg_def_t output_rc_stats_arg =
|
|
||||||
ARG_DEF("rcstat", "output_rc_stats", 1, "output rc stats");
|
|
||||||
#endif
|
|
||||||
static const arg_def_t width_arg = ARG_DEF("w", "width", 1, "source width");
|
|
||||||
static const arg_def_t height_arg = ARG_DEF("h", "height", 1, "source height");
|
|
||||||
static const arg_def_t timebase_arg =
|
|
||||||
ARG_DEF("t", "timebase", 1, "timebase (num/den)");
|
|
||||||
static const arg_def_t bitrate_arg = ARG_DEF(
|
|
||||||
"b", "target-bitrate", 1, "encoding bitrate, in kilobits per second");
|
|
||||||
static const arg_def_t spatial_layers_arg =
|
|
||||||
ARG_DEF("sl", "spatial-layers", 1, "number of spatial SVC layers");
|
|
||||||
static const arg_def_t temporal_layers_arg =
|
|
||||||
ARG_DEF("tl", "temporal-layers", 1, "number of temporal SVC layers");
|
|
||||||
static const arg_def_t temporal_layering_mode_arg =
|
|
||||||
ARG_DEF("tlm", "temporal-layering-mode", 1,
|
|
||||||
"temporal layering scheme."
|
|
||||||
"VP9E_TEMPORAL_LAYERING_MODE");
|
|
||||||
static const arg_def_t kf_dist_arg =
|
|
||||||
ARG_DEF("k", "kf-dist", 1, "number of frames between keyframes");
|
|
||||||
static const arg_def_t scale_factors_arg =
|
|
||||||
ARG_DEF("r", "scale-factors", 1, "scale factors (lowest to highest layer)");
|
|
||||||
static const arg_def_t passes_arg =
|
|
||||||
ARG_DEF("p", "passes", 1, "Number of passes (1/2)");
|
|
||||||
static const arg_def_t pass_arg =
|
|
||||||
ARG_DEF(NULL, "pass", 1, "Pass to execute (1/2)");
|
|
||||||
static const arg_def_t fpf_name_arg =
|
|
||||||
ARG_DEF(NULL, "fpf", 1, "First pass statistics file name");
|
|
||||||
static const arg_def_t min_q_arg =
|
|
||||||
ARG_DEF(NULL, "min-q", 1, "Minimum quantizer");
|
|
||||||
static const arg_def_t max_q_arg =
|
|
||||||
ARG_DEF(NULL, "max-q", 1, "Maximum quantizer");
|
|
||||||
static const arg_def_t min_bitrate_arg =
|
|
||||||
ARG_DEF(NULL, "min-bitrate", 1, "Minimum bitrate");
|
|
||||||
static const arg_def_t max_bitrate_arg =
|
|
||||||
ARG_DEF(NULL, "max-bitrate", 1, "Maximum bitrate");
|
|
||||||
static const arg_def_t lag_in_frame_arg =
|
|
||||||
ARG_DEF(NULL, "lag-in-frames", 1,
|
|
||||||
"Number of frame to input before "
|
|
||||||
"generating any outputs");
|
|
||||||
static const arg_def_t rc_end_usage_arg =
|
|
||||||
ARG_DEF(NULL, "rc-end-usage", 1, "0 - 3: VBR, CBR, CQ, Q");
|
|
||||||
static const arg_def_t speed_arg =
|
|
||||||
ARG_DEF("sp", "speed", 1, "speed configuration");
|
|
||||||
static const arg_def_t aqmode_arg =
|
|
||||||
ARG_DEF("aq", "aqmode", 1, "aq-mode off/on");
|
|
||||||
static const arg_def_t bitrates_arg =
|
|
||||||
ARG_DEF("bl", "bitrates", 1, "bitrates[sl * num_tl + tl]");
|
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
static const struct arg_enum_list bitdepth_enum[] = {
|
|
||||||
{ "8", VPX_BITS_8 }, { "10", VPX_BITS_10 }, { "12", VPX_BITS_12 }, { NULL, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const arg_def_t bitdepth_arg = ARG_DEF_ENUM(
|
|
||||||
"d", "bit-depth", 1, "Bit depth for codec 8, 10 or 12. ", bitdepth_enum);
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
|
|
||||||
static const arg_def_t *svc_args[] = { &frames_arg,
|
|
||||||
&width_arg,
|
|
||||||
&height_arg,
|
|
||||||
&timebase_arg,
|
|
||||||
&bitrate_arg,
|
|
||||||
&skip_frames_arg,
|
|
||||||
&spatial_layers_arg,
|
|
||||||
&kf_dist_arg,
|
|
||||||
&scale_factors_arg,
|
|
||||||
&passes_arg,
|
|
||||||
&pass_arg,
|
|
||||||
&fpf_name_arg,
|
|
||||||
&min_q_arg,
|
|
||||||
&max_q_arg,
|
|
||||||
&min_bitrate_arg,
|
|
||||||
&max_bitrate_arg,
|
|
||||||
&temporal_layers_arg,
|
|
||||||
&temporal_layering_mode_arg,
|
|
||||||
&lag_in_frame_arg,
|
|
||||||
&threads_arg,
|
|
||||||
&aqmode_arg,
|
|
||||||
#if OUTPUT_RC_STATS
|
|
||||||
&output_rc_stats_arg,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
&bitdepth_arg,
|
|
||||||
#endif
|
|
||||||
&speed_arg,
|
|
||||||
&rc_end_usage_arg,
|
|
||||||
&bitrates_arg,
|
|
||||||
NULL };
|
|
||||||
|
|
||||||
static const uint32_t default_frames_to_skip = 0;
|
|
||||||
static const uint32_t default_frames_to_code = 60 * 60;
|
|
||||||
static const uint32_t default_width = 1920;
|
|
||||||
static const uint32_t default_height = 1080;
|
|
||||||
static const uint32_t default_timebase_num = 1;
|
|
||||||
static const uint32_t default_timebase_den = 60;
|
|
||||||
static const uint32_t default_bitrate = 1000;
|
|
||||||
static const uint32_t default_spatial_layers = 5;
|
|
||||||
static const uint32_t default_temporal_layers = 1;
|
|
||||||
static const uint32_t default_kf_dist = 100;
|
|
||||||
static const uint32_t default_temporal_layering_mode = 0;
|
|
||||||
static const uint32_t default_output_rc_stats = 0;
|
|
||||||
static const int32_t default_speed = -1; // -1 means use library default.
|
|
||||||
static const uint32_t default_threads = 0; // zero means use library default.
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char *input_filename;
|
|
||||||
const char *output_filename;
|
|
||||||
uint32_t frames_to_code;
|
|
||||||
uint32_t frames_to_skip;
|
|
||||||
struct VpxInputContext input_ctx;
|
|
||||||
stats_io_t rc_stats;
|
|
||||||
int passes;
|
|
||||||
int pass;
|
|
||||||
} AppInput;
|
|
||||||
|
|
||||||
static const char *exec_name;
|
|
||||||
|
|
||||||
void usage_exit(void) {
|
|
||||||
fprintf(stderr, "Usage: %s <options> input_filename output_filename\n",
|
|
||||||
exec_name);
|
|
||||||
fprintf(stderr, "Options:\n");
|
|
||||||
arg_show_usage(stderr, svc_args);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void parse_command_line(int argc, const char **argv_,
|
|
||||||
AppInput *app_input, SvcContext *svc_ctx,
|
|
||||||
vpx_codec_enc_cfg_t *enc_cfg) {
|
|
||||||
struct arg arg;
|
|
||||||
char **argv = NULL;
|
|
||||||
char **argi = NULL;
|
|
||||||
char **argj = NULL;
|
|
||||||
vpx_codec_err_t res;
|
|
||||||
int passes = 0;
|
|
||||||
int pass = 0;
|
|
||||||
const char *fpf_file_name = NULL;
|
|
||||||
unsigned int min_bitrate = 0;
|
|
||||||
unsigned int max_bitrate = 0;
|
|
||||||
char string_options[1024] = { 0 };
|
|
||||||
|
|
||||||
// initialize SvcContext with parameters that will be passed to vpx_svc_init
|
|
||||||
svc_ctx->log_level = SVC_LOG_DEBUG;
|
|
||||||
svc_ctx->spatial_layers = default_spatial_layers;
|
|
||||||
svc_ctx->temporal_layers = default_temporal_layers;
|
|
||||||
svc_ctx->temporal_layering_mode = default_temporal_layering_mode;
|
|
||||||
#if OUTPUT_RC_STATS
|
|
||||||
svc_ctx->output_rc_stat = default_output_rc_stats;
|
|
||||||
#endif
|
|
||||||
svc_ctx->speed = default_speed;
|
|
||||||
svc_ctx->threads = default_threads;
|
|
||||||
|
|
||||||
// start with default encoder configuration
|
|
||||||
res = vpx_codec_enc_config_default(vpx_codec_vp9_cx(), enc_cfg, 0);
|
|
||||||
if (res) {
|
|
||||||
die("Failed to get config: %s\n", vpx_codec_err_to_string(res));
|
|
||||||
}
|
|
||||||
// update enc_cfg with app default values
|
|
||||||
enc_cfg->g_w = default_width;
|
|
||||||
enc_cfg->g_h = default_height;
|
|
||||||
enc_cfg->g_timebase.num = default_timebase_num;
|
|
||||||
enc_cfg->g_timebase.den = default_timebase_den;
|
|
||||||
enc_cfg->rc_target_bitrate = default_bitrate;
|
|
||||||
enc_cfg->kf_min_dist = default_kf_dist;
|
|
||||||
enc_cfg->kf_max_dist = default_kf_dist;
|
|
||||||
enc_cfg->rc_end_usage = VPX_CQ;
|
|
||||||
|
|
||||||
// initialize AppInput with default values
|
|
||||||
app_input->frames_to_code = default_frames_to_code;
|
|
||||||
app_input->frames_to_skip = default_frames_to_skip;
|
|
||||||
|
|
||||||
// process command line options
|
|
||||||
argv = argv_dup(argc - 1, argv_ + 1);
|
|
||||||
for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
|
|
||||||
arg.argv_step = 1;
|
|
||||||
|
|
||||||
if (arg_match(&arg, &frames_arg, argi)) {
|
|
||||||
app_input->frames_to_code = arg_parse_uint(&arg);
|
|
||||||
} else if (arg_match(&arg, &width_arg, argi)) {
|
|
||||||
enc_cfg->g_w = arg_parse_uint(&arg);
|
|
||||||
} else if (arg_match(&arg, &height_arg, argi)) {
|
|
||||||
enc_cfg->g_h = arg_parse_uint(&arg);
|
|
||||||
} else if (arg_match(&arg, &timebase_arg, argi)) {
|
|
||||||
enc_cfg->g_timebase = arg_parse_rational(&arg);
|
|
||||||
} else if (arg_match(&arg, &bitrate_arg, argi)) {
|
|
||||||
enc_cfg->rc_target_bitrate = arg_parse_uint(&arg);
|
|
||||||
} else if (arg_match(&arg, &skip_frames_arg, argi)) {
|
|
||||||
app_input->frames_to_skip = arg_parse_uint(&arg);
|
|
||||||
} else if (arg_match(&arg, &spatial_layers_arg, argi)) {
|
|
||||||
svc_ctx->spatial_layers = arg_parse_uint(&arg);
|
|
||||||
} else if (arg_match(&arg, &temporal_layers_arg, argi)) {
|
|
||||||
svc_ctx->temporal_layers = arg_parse_uint(&arg);
|
|
||||||
#if OUTPUT_RC_STATS
|
|
||||||
} else if (arg_match(&arg, &output_rc_stats_arg, argi)) {
|
|
||||||
svc_ctx->output_rc_stat = arg_parse_uint(&arg);
|
|
||||||
#endif
|
|
||||||
} else if (arg_match(&arg, &speed_arg, argi)) {
|
|
||||||
svc_ctx->speed = arg_parse_uint(&arg);
|
|
||||||
} else if (arg_match(&arg, &aqmode_arg, argi)) {
|
|
||||||
svc_ctx->aqmode = arg_parse_uint(&arg);
|
|
||||||
} else if (arg_match(&arg, &threads_arg, argi)) {
|
|
||||||
svc_ctx->threads = arg_parse_uint(&arg);
|
|
||||||
} else if (arg_match(&arg, &temporal_layering_mode_arg, argi)) {
|
|
||||||
svc_ctx->temporal_layering_mode = enc_cfg->temporal_layering_mode =
|
|
||||||
arg_parse_int(&arg);
|
|
||||||
if (svc_ctx->temporal_layering_mode) {
|
|
||||||
enc_cfg->g_error_resilient = 1;
|
|
||||||
}
|
|
||||||
} else if (arg_match(&arg, &kf_dist_arg, argi)) {
|
|
||||||
enc_cfg->kf_min_dist = arg_parse_uint(&arg);
|
|
||||||
enc_cfg->kf_max_dist = enc_cfg->kf_min_dist;
|
|
||||||
} else if (arg_match(&arg, &scale_factors_arg, argi)) {
|
|
||||||
snprintf(string_options, sizeof(string_options), "%s scale-factors=%s",
|
|
||||||
string_options, arg.val);
|
|
||||||
} else if (arg_match(&arg, &bitrates_arg, argi)) {
|
|
||||||
snprintf(string_options, sizeof(string_options), "%s bitrates=%s",
|
|
||||||
string_options, arg.val);
|
|
||||||
} else if (arg_match(&arg, &passes_arg, argi)) {
|
|
||||||
passes = arg_parse_uint(&arg);
|
|
||||||
if (passes < 1 || passes > 2) {
|
|
||||||
die("Error: Invalid number of passes (%d)\n", passes);
|
|
||||||
}
|
|
||||||
} else if (arg_match(&arg, &pass_arg, argi)) {
|
|
||||||
pass = arg_parse_uint(&arg);
|
|
||||||
if (pass < 1 || pass > 2) {
|
|
||||||
die("Error: Invalid pass selected (%d)\n", pass);
|
|
||||||
}
|
|
||||||
} else if (arg_match(&arg, &fpf_name_arg, argi)) {
|
|
||||||
fpf_file_name = arg.val;
|
|
||||||
} else if (arg_match(&arg, &min_q_arg, argi)) {
|
|
||||||
snprintf(string_options, sizeof(string_options), "%s min-quantizers=%s",
|
|
||||||
string_options, arg.val);
|
|
||||||
} else if (arg_match(&arg, &max_q_arg, argi)) {
|
|
||||||
snprintf(string_options, sizeof(string_options), "%s max-quantizers=%s",
|
|
||||||
string_options, arg.val);
|
|
||||||
} else if (arg_match(&arg, &min_bitrate_arg, argi)) {
|
|
||||||
min_bitrate = arg_parse_uint(&arg);
|
|
||||||
} else if (arg_match(&arg, &max_bitrate_arg, argi)) {
|
|
||||||
max_bitrate = arg_parse_uint(&arg);
|
|
||||||
} else if (arg_match(&arg, &lag_in_frame_arg, argi)) {
|
|
||||||
enc_cfg->g_lag_in_frames = arg_parse_uint(&arg);
|
|
||||||
} else if (arg_match(&arg, &rc_end_usage_arg, argi)) {
|
|
||||||
enc_cfg->rc_end_usage = arg_parse_uint(&arg);
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
} else if (arg_match(&arg, &bitdepth_arg, argi)) {
|
|
||||||
enc_cfg->g_bit_depth = arg_parse_enum_or_int(&arg);
|
|
||||||
switch (enc_cfg->g_bit_depth) {
|
|
||||||
case VPX_BITS_8:
|
|
||||||
enc_cfg->g_input_bit_depth = 8;
|
|
||||||
enc_cfg->g_profile = 0;
|
|
||||||
break;
|
|
||||||
case VPX_BITS_10:
|
|
||||||
enc_cfg->g_input_bit_depth = 10;
|
|
||||||
enc_cfg->g_profile = 2;
|
|
||||||
break;
|
|
||||||
case VPX_BITS_12:
|
|
||||||
enc_cfg->g_input_bit_depth = 12;
|
|
||||||
enc_cfg->g_profile = 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
die("Error: Invalid bit depth selected (%d)\n", enc_cfg->g_bit_depth);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
} else {
|
|
||||||
++argj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// There will be a space in front of the string options
|
|
||||||
if (strlen(string_options) > 0)
|
|
||||||
vpx_svc_set_options(svc_ctx, string_options + 1);
|
|
||||||
|
|
||||||
if (passes == 0 || passes == 1) {
|
|
||||||
if (pass) {
|
|
||||||
fprintf(stderr, "pass is ignored since there's only one pass\n");
|
|
||||||
}
|
|
||||||
enc_cfg->g_pass = VPX_RC_ONE_PASS;
|
|
||||||
} else {
|
|
||||||
if (pass == 0) {
|
|
||||||
die("pass must be specified when passes is 2\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fpf_file_name == NULL) {
|
|
||||||
die("fpf must be specified when passes is 2\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pass == 1) {
|
|
||||||
enc_cfg->g_pass = VPX_RC_FIRST_PASS;
|
|
||||||
if (!stats_open_file(&app_input->rc_stats, fpf_file_name, 0)) {
|
|
||||||
fatal("Failed to open statistics store");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
enc_cfg->g_pass = VPX_RC_LAST_PASS;
|
|
||||||
if (!stats_open_file(&app_input->rc_stats, fpf_file_name, 1)) {
|
|
||||||
fatal("Failed to open statistics store");
|
|
||||||
}
|
|
||||||
enc_cfg->rc_twopass_stats_in = stats_get(&app_input->rc_stats);
|
|
||||||
}
|
|
||||||
app_input->passes = passes;
|
|
||||||
app_input->pass = pass;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enc_cfg->rc_target_bitrate > 0) {
|
|
||||||
if (min_bitrate > 0) {
|
|
||||||
enc_cfg->rc_2pass_vbr_minsection_pct =
|
|
||||||
min_bitrate * 100 / enc_cfg->rc_target_bitrate;
|
|
||||||
}
|
|
||||||
if (max_bitrate > 0) {
|
|
||||||
enc_cfg->rc_2pass_vbr_maxsection_pct =
|
|
||||||
max_bitrate * 100 / enc_cfg->rc_target_bitrate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for unrecognized options
|
|
||||||
for (argi = argv; *argi; ++argi)
|
|
||||||
if (argi[0][0] == '-' && strlen(argi[0]) > 1)
|
|
||||||
die("Error: Unrecognized option %s\n", *argi);
|
|
||||||
|
|
||||||
if (argv[0] == NULL || argv[1] == 0) {
|
|
||||||
usage_exit();
|
|
||||||
}
|
|
||||||
app_input->input_filename = argv[0];
|
|
||||||
app_input->output_filename = argv[1];
|
|
||||||
free(argv);
|
|
||||||
|
|
||||||
if (enc_cfg->g_w < 16 || enc_cfg->g_w % 2 || enc_cfg->g_h < 16 ||
|
|
||||||
enc_cfg->g_h % 2)
|
|
||||||
die("Invalid resolution: %d x %d\n", enc_cfg->g_w, enc_cfg->g_h);
|
|
||||||
|
|
||||||
printf(
|
|
||||||
"Codec %s\nframes: %d, skip: %d\n"
|
|
||||||
"layers: %d\n"
|
|
||||||
"width %d, height: %d,\n"
|
|
||||||
"num: %d, den: %d, bitrate: %d,\n"
|
|
||||||
"gop size: %d\n",
|
|
||||||
vpx_codec_iface_name(vpx_codec_vp9_cx()), app_input->frames_to_code,
|
|
||||||
app_input->frames_to_skip, svc_ctx->spatial_layers, enc_cfg->g_w,
|
|
||||||
enc_cfg->g_h, enc_cfg->g_timebase.num, enc_cfg->g_timebase.den,
|
|
||||||
enc_cfg->rc_target_bitrate, enc_cfg->kf_max_dist);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if OUTPUT_RC_STATS
|
|
||||||
// For rate control encoding stats.
|
|
||||||
struct RateControlStats {
|
|
||||||
// Number of input frames per layer.
|
|
||||||
int layer_input_frames[VPX_MAX_LAYERS];
|
|
||||||
// Total (cumulative) number of encoded frames per layer.
|
|
||||||
int layer_tot_enc_frames[VPX_MAX_LAYERS];
|
|
||||||
// Number of encoded non-key frames per layer.
|
|
||||||
int layer_enc_frames[VPX_MAX_LAYERS];
|
|
||||||
// Framerate per layer (cumulative).
|
|
||||||
double layer_framerate[VPX_MAX_LAYERS];
|
|
||||||
// Target average frame size per layer (per-frame-bandwidth per layer).
|
|
||||||
double layer_pfb[VPX_MAX_LAYERS];
|
|
||||||
// Actual average frame size per layer.
|
|
||||||
double layer_avg_frame_size[VPX_MAX_LAYERS];
|
|
||||||
// Average rate mismatch per layer (|target - actual| / target).
|
|
||||||
double layer_avg_rate_mismatch[VPX_MAX_LAYERS];
|
|
||||||
// Actual encoding bitrate per layer (cumulative).
|
|
||||||
double layer_encoding_bitrate[VPX_MAX_LAYERS];
|
|
||||||
// Average of the short-time encoder actual bitrate.
|
|
||||||
// TODO(marpan): Should we add these short-time stats for each layer?
|
|
||||||
double avg_st_encoding_bitrate;
|
|
||||||
// Variance of the short-time encoder actual bitrate.
|
|
||||||
double variance_st_encoding_bitrate;
|
|
||||||
// Window (number of frames) for computing short-time encoding bitrate.
|
|
||||||
int window_size;
|
|
||||||
// Number of window measurements.
|
|
||||||
int window_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Note: these rate control stats assume only 1 key frame in the
|
|
||||||
// sequence (i.e., first frame only).
|
|
||||||
static void set_rate_control_stats(struct RateControlStats *rc,
|
|
||||||
vpx_codec_enc_cfg_t *cfg) {
|
|
||||||
unsigned int sl, tl;
|
|
||||||
// Set the layer (cumulative) framerate and the target layer (non-cumulative)
|
|
||||||
// per-frame-bandwidth, for the rate control encoding stats below.
|
|
||||||
const double framerate = cfg->g_timebase.den / cfg->g_timebase.num;
|
|
||||||
|
|
||||||
for (sl = 0; sl < cfg->ss_number_layers; ++sl) {
|
|
||||||
for (tl = 0; tl < cfg->ts_number_layers; ++tl) {
|
|
||||||
const int layer = sl * cfg->ts_number_layers + tl;
|
|
||||||
if (cfg->ts_number_layers == 1)
|
|
||||||
rc->layer_framerate[layer] = framerate;
|
|
||||||
else
|
|
||||||
rc->layer_framerate[layer] = framerate / cfg->ts_rate_decimator[tl];
|
|
||||||
if (tl > 0) {
|
|
||||||
rc->layer_pfb[layer] =
|
|
||||||
1000.0 * (cfg->layer_target_bitrate[layer] -
|
|
||||||
cfg->layer_target_bitrate[layer - 1]) /
|
|
||||||
(rc->layer_framerate[layer] - rc->layer_framerate[layer - 1]);
|
|
||||||
} else {
|
|
||||||
rc->layer_pfb[layer] = 1000.0 * cfg->layer_target_bitrate[layer] /
|
|
||||||
rc->layer_framerate[layer];
|
|
||||||
}
|
|
||||||
rc->layer_input_frames[layer] = 0;
|
|
||||||
rc->layer_enc_frames[layer] = 0;
|
|
||||||
rc->layer_tot_enc_frames[layer] = 0;
|
|
||||||
rc->layer_encoding_bitrate[layer] = 0.0;
|
|
||||||
rc->layer_avg_frame_size[layer] = 0.0;
|
|
||||||
rc->layer_avg_rate_mismatch[layer] = 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rc->window_count = 0;
|
|
||||||
rc->window_size = 15;
|
|
||||||
rc->avg_st_encoding_bitrate = 0.0;
|
|
||||||
rc->variance_st_encoding_bitrate = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void printout_rate_control_summary(struct RateControlStats *rc,
|
|
||||||
vpx_codec_enc_cfg_t *cfg,
|
|
||||||
int frame_cnt) {
|
|
||||||
unsigned int sl, tl;
|
|
||||||
double perc_fluctuation = 0.0;
|
|
||||||
int tot_num_frames = 0;
|
|
||||||
printf("Total number of processed frames: %d\n\n", frame_cnt - 1);
|
|
||||||
printf("Rate control layer stats for sl%d tl%d layer(s):\n\n",
|
|
||||||
cfg->ss_number_layers, cfg->ts_number_layers);
|
|
||||||
for (sl = 0; sl < cfg->ss_number_layers; ++sl) {
|
|
||||||
tot_num_frames = 0;
|
|
||||||
for (tl = 0; tl < cfg->ts_number_layers; ++tl) {
|
|
||||||
const int layer = sl * cfg->ts_number_layers + tl;
|
|
||||||
const int num_dropped =
|
|
||||||
(tl > 0)
|
|
||||||
? (rc->layer_input_frames[layer] - rc->layer_enc_frames[layer])
|
|
||||||
: (rc->layer_input_frames[layer] - rc->layer_enc_frames[layer] -
|
|
||||||
1);
|
|
||||||
tot_num_frames += rc->layer_input_frames[layer];
|
|
||||||
rc->layer_encoding_bitrate[layer] = 0.001 * rc->layer_framerate[layer] *
|
|
||||||
rc->layer_encoding_bitrate[layer] /
|
|
||||||
tot_num_frames;
|
|
||||||
rc->layer_avg_frame_size[layer] =
|
|
||||||
rc->layer_avg_frame_size[layer] / rc->layer_enc_frames[layer];
|
|
||||||
rc->layer_avg_rate_mismatch[layer] = 100.0 *
|
|
||||||
rc->layer_avg_rate_mismatch[layer] /
|
|
||||||
rc->layer_enc_frames[layer];
|
|
||||||
printf("For layer#: sl%d tl%d \n", sl, tl);
|
|
||||||
printf("Bitrate (target vs actual): %d %f.0 kbps\n",
|
|
||||||
cfg->layer_target_bitrate[layer],
|
|
||||||
rc->layer_encoding_bitrate[layer]);
|
|
||||||
printf("Average frame size (target vs actual): %f %f bits\n",
|
|
||||||
rc->layer_pfb[layer], rc->layer_avg_frame_size[layer]);
|
|
||||||
printf("Average rate_mismatch: %f\n", rc->layer_avg_rate_mismatch[layer]);
|
|
||||||
printf(
|
|
||||||
"Number of input frames, encoded (non-key) frames, "
|
|
||||||
"and percent dropped frames: %d %d %f.0 \n",
|
|
||||||
rc->layer_input_frames[layer], rc->layer_enc_frames[layer],
|
|
||||||
100.0 * num_dropped / rc->layer_input_frames[layer]);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rc->avg_st_encoding_bitrate = rc->avg_st_encoding_bitrate / rc->window_count;
|
|
||||||
rc->variance_st_encoding_bitrate =
|
|
||||||
rc->variance_st_encoding_bitrate / rc->window_count -
|
|
||||||
(rc->avg_st_encoding_bitrate * rc->avg_st_encoding_bitrate);
|
|
||||||
perc_fluctuation = 100.0 * sqrt(rc->variance_st_encoding_bitrate) /
|
|
||||||
rc->avg_st_encoding_bitrate;
|
|
||||||
printf("Short-time stats, for window of %d frames: \n", rc->window_size);
|
|
||||||
printf("Average, rms-variance, and percent-fluct: %f %f %f \n",
|
|
||||||
rc->avg_st_encoding_bitrate, sqrt(rc->variance_st_encoding_bitrate),
|
|
||||||
perc_fluctuation);
|
|
||||||
if (frame_cnt != tot_num_frames)
|
|
||||||
die("Error: Number of input frames not equal to output encoded frames != "
|
|
||||||
"%d tot_num_frames = %d\n",
|
|
||||||
frame_cnt, tot_num_frames);
|
|
||||||
}
|
|
||||||
|
|
||||||
vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
|
|
||||||
uint64_t sizes[8], int *count) {
|
|
||||||
// A chunk ending with a byte matching 0xc0 is an invalid chunk unless
|
|
||||||
// it is a super frame index. If the last byte of real video compression
|
|
||||||
// data is 0xc0 the encoder must add a 0 byte. If we have the marker but
|
|
||||||
// not the associated matching marker byte at the front of the index we have
|
|
||||||
// an invalid bitstream and need to return an error.
|
|
||||||
|
|
||||||
uint8_t marker;
|
|
||||||
|
|
||||||
marker = *(data + data_sz - 1);
|
|
||||||
*count = 0;
|
|
||||||
|
|
||||||
if ((marker & 0xe0) == 0xc0) {
|
|
||||||
const uint32_t frames = (marker & 0x7) + 1;
|
|
||||||
const uint32_t mag = ((marker >> 3) & 0x3) + 1;
|
|
||||||
const size_t index_sz = 2 + mag * frames;
|
|
||||||
|
|
||||||
// This chunk is marked as having a superframe index but doesn't have
|
|
||||||
// enough data for it, thus it's an invalid superframe index.
|
|
||||||
if (data_sz < index_sz) return VPX_CODEC_CORRUPT_FRAME;
|
|
||||||
|
|
||||||
{
|
|
||||||
const uint8_t marker2 = *(data + data_sz - index_sz);
|
|
||||||
|
|
||||||
// This chunk is marked as having a superframe index but doesn't have
|
|
||||||
// the matching marker byte at the front of the index therefore it's an
|
|
||||||
// invalid chunk.
|
|
||||||
if (marker != marker2) return VPX_CODEC_CORRUPT_FRAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// Found a valid superframe index.
|
|
||||||
uint32_t i, j;
|
|
||||||
const uint8_t *x = &data[data_sz - index_sz + 1];
|
|
||||||
|
|
||||||
for (i = 0; i < frames; ++i) {
|
|
||||||
uint32_t this_sz = 0;
|
|
||||||
|
|
||||||
for (j = 0; j < mag; ++j) this_sz |= (*x++) << (j * 8);
|
|
||||||
sizes[i] = this_sz;
|
|
||||||
}
|
|
||||||
*count = frames;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return VPX_CODEC_OK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Example pattern for spatial layers and 2 temporal layers used in the
|
|
||||||
// bypass/flexible mode. The pattern corresponds to the pattern
|
|
||||||
// VP9E_TEMPORAL_LAYERING_MODE_0101 (temporal_layering_mode == 2) used in
|
|
||||||
// non-flexible mode.
|
|
||||||
void set_frame_flags_bypass_mode(int sl, int tl, int num_spatial_layers,
|
|
||||||
int is_key_frame,
|
|
||||||
vpx_svc_ref_frame_config_t *ref_frame_config) {
|
|
||||||
for (sl = 0; sl < num_spatial_layers; ++sl) {
|
|
||||||
if (!tl) {
|
|
||||||
if (!sl) {
|
|
||||||
ref_frame_config->frame_flags[sl] =
|
|
||||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
|
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
} else {
|
|
||||||
if (is_key_frame) {
|
|
||||||
ref_frame_config->frame_flags[sl] =
|
|
||||||
VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_ARF |
|
|
||||||
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
} else {
|
|
||||||
ref_frame_config->frame_flags[sl] =
|
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (tl == 1) {
|
|
||||||
if (!sl) {
|
|
||||||
ref_frame_config->frame_flags[sl] =
|
|
||||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
|
|
||||||
VP8_EFLAG_NO_UPD_GF;
|
|
||||||
} else {
|
|
||||||
ref_frame_config->frame_flags[sl] =
|
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tl == 0) {
|
|
||||||
ref_frame_config->lst_fb_idx[sl] = sl;
|
|
||||||
if (sl)
|
|
||||||
ref_frame_config->gld_fb_idx[sl] = sl - 1;
|
|
||||||
else
|
|
||||||
ref_frame_config->gld_fb_idx[sl] = 0;
|
|
||||||
ref_frame_config->alt_fb_idx[sl] = 0;
|
|
||||||
} else if (tl == 1) {
|
|
||||||
ref_frame_config->lst_fb_idx[sl] = sl;
|
|
||||||
ref_frame_config->gld_fb_idx[sl] = num_spatial_layers + sl - 1;
|
|
||||||
ref_frame_config->alt_fb_idx[sl] = num_spatial_layers + sl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, const char **argv) {
|
|
||||||
AppInput app_input;
|
|
||||||
VpxVideoWriter *writer = NULL;
|
|
||||||
VpxVideoInfo info;
|
|
||||||
vpx_codec_ctx_t codec;
|
|
||||||
vpx_codec_enc_cfg_t enc_cfg;
|
|
||||||
SvcContext svc_ctx;
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t frame_cnt = 0;
|
|
||||||
vpx_image_t raw;
|
|
||||||
vpx_codec_err_t res;
|
|
||||||
int pts = 0; /* PTS starts at 0 */
|
|
||||||
int frame_duration = 1; /* 1 timebase tick per frame */
|
|
||||||
FILE *infile = NULL;
|
|
||||||
int end_of_stream = 0;
|
|
||||||
int frames_received = 0;
|
|
||||||
#if OUTPUT_RC_STATS
|
|
||||||
VpxVideoWriter *outfile[VPX_TS_MAX_LAYERS] = { NULL };
|
|
||||||
struct RateControlStats rc;
|
|
||||||
vpx_svc_layer_id_t layer_id;
|
|
||||||
vpx_svc_ref_frame_config_t ref_frame_config;
|
|
||||||
unsigned int sl, tl;
|
|
||||||
double sum_bitrate = 0.0;
|
|
||||||
double sum_bitrate2 = 0.0;
|
|
||||||
double framerate = 30.0;
|
|
||||||
#endif
|
|
||||||
struct vpx_usec_timer timer;
|
|
||||||
int64_t cx_time = 0;
|
|
||||||
memset(&svc_ctx, 0, sizeof(svc_ctx));
|
|
||||||
svc_ctx.log_print = 1;
|
|
||||||
exec_name = argv[0];
|
|
||||||
parse_command_line(argc, argv, &app_input, &svc_ctx, &enc_cfg);
|
|
||||||
|
|
||||||
// Allocate image buffer
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
if (!vpx_img_alloc(&raw,
|
|
||||||
enc_cfg.g_input_bit_depth == 8 ? VPX_IMG_FMT_I420
|
|
||||||
: VPX_IMG_FMT_I42016,
|
|
||||||
enc_cfg.g_w, enc_cfg.g_h, 32)) {
|
|
||||||
die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, enc_cfg.g_w, enc_cfg.g_h, 32)) {
|
|
||||||
die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h);
|
|
||||||
}
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
|
|
||||||
if (!(infile = fopen(app_input.input_filename, "rb")))
|
|
||||||
die("Failed to open %s for reading\n", app_input.input_filename);
|
|
||||||
|
|
||||||
// Initialize codec
|
|
||||||
if (vpx_svc_init(&svc_ctx, &codec, vpx_codec_vp9_cx(), &enc_cfg) !=
|
|
||||||
VPX_CODEC_OK)
|
|
||||||
die("Failed to initialize encoder\n");
|
|
||||||
|
|
||||||
#if OUTPUT_RC_STATS
|
|
||||||
if (svc_ctx.output_rc_stat) {
|
|
||||||
set_rate_control_stats(&rc, &enc_cfg);
|
|
||||||
framerate = enc_cfg.g_timebase.den / enc_cfg.g_timebase.num;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
info.codec_fourcc = VP9_FOURCC;
|
|
||||||
info.time_base.numerator = enc_cfg.g_timebase.num;
|
|
||||||
info.time_base.denominator = enc_cfg.g_timebase.den;
|
|
||||||
|
|
||||||
if (!(app_input.passes == 2 && app_input.pass == 1)) {
|
|
||||||
// We don't save the bitstream for the 1st pass on two pass rate control
|
|
||||||
writer =
|
|
||||||
vpx_video_writer_open(app_input.output_filename, kContainerIVF, &info);
|
|
||||||
if (!writer)
|
|
||||||
die("Failed to open %s for writing\n", app_input.output_filename);
|
|
||||||
}
|
|
||||||
#if OUTPUT_RC_STATS
|
|
||||||
// For now, just write temporal layer streams.
|
|
||||||
// TODO(marpan): do spatial by re-writing superframe.
|
|
||||||
if (svc_ctx.output_rc_stat) {
|
|
||||||
for (tl = 0; tl < enc_cfg.ts_number_layers; ++tl) {
|
|
||||||
char file_name[PATH_MAX];
|
|
||||||
|
|
||||||
snprintf(file_name, sizeof(file_name), "%s_t%d.ivf",
|
|
||||||
app_input.output_filename, tl);
|
|
||||||
outfile[tl] = vpx_video_writer_open(file_name, kContainerIVF, &info);
|
|
||||||
if (!outfile[tl]) die("Failed to open %s for writing", file_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// skip initial frames
|
|
||||||
for (i = 0; i < app_input.frames_to_skip; ++i) vpx_img_read(&raw, infile);
|
|
||||||
|
|
||||||
if (svc_ctx.speed != -1)
|
|
||||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, svc_ctx.speed);
|
|
||||||
if (svc_ctx.threads) {
|
|
||||||
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (svc_ctx.threads >> 1));
|
|
||||||
if (svc_ctx.threads > 1)
|
|
||||||
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 1);
|
|
||||||
else
|
|
||||||
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 0);
|
|
||||||
}
|
|
||||||
if (svc_ctx.speed >= 5 && svc_ctx.aqmode == 1)
|
|
||||||
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
|
|
||||||
if (svc_ctx.speed >= 5)
|
|
||||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
|
||||||
vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT, 900);
|
|
||||||
|
|
||||||
// Encode frames
|
|
||||||
while (!end_of_stream) {
|
|
||||||
vpx_codec_iter_t iter = NULL;
|
|
||||||
const vpx_codec_cx_pkt_t *cx_pkt;
|
|
||||||
if (frame_cnt >= app_input.frames_to_code || !vpx_img_read(&raw, infile)) {
|
|
||||||
// We need one extra vpx_svc_encode call at end of stream to flush
|
|
||||||
// encoder and get remaining data
|
|
||||||
end_of_stream = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For BYPASS/FLEXIBLE mode, set the frame flags (reference and updates)
|
|
||||||
// and the buffer indices for each spatial layer of the current
|
|
||||||
// (super)frame to be encoded. The temporal layer_id for the current frame
|
|
||||||
// also needs to be set.
|
|
||||||
// TODO(marpan): Should rename the "VP9E_TEMPORAL_LAYERING_MODE_BYPASS"
|
|
||||||
// mode to "VP9E_LAYERING_MODE_BYPASS".
|
|
||||||
if (svc_ctx.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
|
|
||||||
layer_id.spatial_layer_id = 0;
|
|
||||||
// Example for 2 temporal layers.
|
|
||||||
if (frame_cnt % 2 == 0)
|
|
||||||
layer_id.temporal_layer_id = 0;
|
|
||||||
else
|
|
||||||
layer_id.temporal_layer_id = 1;
|
|
||||||
// Note that we only set the temporal layer_id, since we are calling
|
|
||||||
// the encode for the whole superframe. The encoder will internally loop
|
|
||||||
// over all the spatial layers for the current superframe.
|
|
||||||
vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id);
|
|
||||||
set_frame_flags_bypass_mode(sl, layer_id.temporal_layer_id,
|
|
||||||
svc_ctx.spatial_layers, frame_cnt == 0,
|
|
||||||
&ref_frame_config);
|
|
||||||
vpx_codec_control(&codec, VP9E_SET_SVC_REF_FRAME_CONFIG,
|
|
||||||
&ref_frame_config);
|
|
||||||
// Keep track of input frames, to account for frame drops in rate control
|
|
||||||
// stats/metrics.
|
|
||||||
for (sl = 0; sl < (unsigned int)enc_cfg.ss_number_layers; ++sl) {
|
|
||||||
++rc.layer_input_frames[sl * enc_cfg.ts_number_layers +
|
|
||||||
layer_id.temporal_layer_id];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vpx_usec_timer_start(&timer);
|
|
||||||
res = vpx_svc_encode(
|
|
||||||
&svc_ctx, &codec, (end_of_stream ? NULL : &raw), pts, frame_duration,
|
|
||||||
svc_ctx.speed >= 5 ? VPX_DL_REALTIME : VPX_DL_GOOD_QUALITY);
|
|
||||||
vpx_usec_timer_mark(&timer);
|
|
||||||
cx_time += vpx_usec_timer_elapsed(&timer);
|
|
||||||
|
|
||||||
printf("%s", vpx_svc_get_message(&svc_ctx));
|
|
||||||
fflush(stdout);
|
|
||||||
if (res != VPX_CODEC_OK) {
|
|
||||||
die_codec(&codec, "Failed to encode frame");
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((cx_pkt = vpx_codec_get_cx_data(&codec, &iter)) != NULL) {
|
|
||||||
switch (cx_pkt->kind) {
|
|
||||||
case VPX_CODEC_CX_FRAME_PKT: {
|
|
||||||
SvcInternal_t *const si = (SvcInternal_t *)svc_ctx.internal;
|
|
||||||
if (cx_pkt->data.frame.sz > 0) {
|
|
||||||
#if OUTPUT_RC_STATS
|
|
||||||
uint64_t sizes[8];
|
|
||||||
int count = 0;
|
|
||||||
#endif
|
|
||||||
vpx_video_writer_write_frame(writer, cx_pkt->data.frame.buf,
|
|
||||||
cx_pkt->data.frame.sz,
|
|
||||||
cx_pkt->data.frame.pts);
|
|
||||||
#if OUTPUT_RC_STATS
|
|
||||||
// TODO(marpan): Put this (to line728) in separate function.
|
|
||||||
if (svc_ctx.output_rc_stat) {
|
|
||||||
vpx_codec_control(&codec, VP9E_GET_SVC_LAYER_ID, &layer_id);
|
|
||||||
parse_superframe_index(cx_pkt->data.frame.buf,
|
|
||||||
cx_pkt->data.frame.sz, sizes, &count);
|
|
||||||
if (enc_cfg.ss_number_layers == 1)
|
|
||||||
sizes[0] = cx_pkt->data.frame.sz;
|
|
||||||
// Note computing input_layer_frames here won't account for frame
|
|
||||||
// drops in rate control stats.
|
|
||||||
// TODO(marpan): Fix this for non-bypass mode so we can get stats
|
|
||||||
// for dropped frames.
|
|
||||||
if (svc_ctx.temporal_layering_mode !=
|
|
||||||
VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
|
|
||||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
|
||||||
++rc.layer_input_frames[sl * enc_cfg.ts_number_layers +
|
|
||||||
layer_id.temporal_layer_id];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (tl = layer_id.temporal_layer_id;
|
|
||||||
tl < enc_cfg.ts_number_layers; ++tl) {
|
|
||||||
vpx_video_writer_write_frame(
|
|
||||||
outfile[tl], cx_pkt->data.frame.buf, cx_pkt->data.frame.sz,
|
|
||||||
cx_pkt->data.frame.pts);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
|
||||||
for (tl = layer_id.temporal_layer_id;
|
|
||||||
tl < enc_cfg.ts_number_layers; ++tl) {
|
|
||||||
const int layer = sl * enc_cfg.ts_number_layers + tl;
|
|
||||||
++rc.layer_tot_enc_frames[layer];
|
|
||||||
rc.layer_encoding_bitrate[layer] += 8.0 * sizes[sl];
|
|
||||||
// Keep count of rate control stats per layer, for non-key
|
|
||||||
// frames.
|
|
||||||
if (tl == (unsigned int)layer_id.temporal_layer_id &&
|
|
||||||
!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
|
|
||||||
rc.layer_avg_frame_size[layer] += 8.0 * sizes[sl];
|
|
||||||
rc.layer_avg_rate_mismatch[layer] +=
|
|
||||||
fabs(8.0 * sizes[sl] - rc.layer_pfb[layer]) /
|
|
||||||
rc.layer_pfb[layer];
|
|
||||||
++rc.layer_enc_frames[layer];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update for short-time encoding bitrate states, for moving
|
|
||||||
// window of size rc->window, shifted by rc->window / 2.
|
|
||||||
// Ignore first window segment, due to key frame.
|
|
||||||
if (frame_cnt > (unsigned int)rc.window_size) {
|
|
||||||
tl = layer_id.temporal_layer_id;
|
|
||||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
|
||||||
sum_bitrate += 0.001 * 8.0 * sizes[sl] * framerate;
|
|
||||||
}
|
|
||||||
if (frame_cnt % rc.window_size == 0) {
|
|
||||||
rc.window_count += 1;
|
|
||||||
rc.avg_st_encoding_bitrate += sum_bitrate / rc.window_size;
|
|
||||||
rc.variance_st_encoding_bitrate +=
|
|
||||||
(sum_bitrate / rc.window_size) *
|
|
||||||
(sum_bitrate / rc.window_size);
|
|
||||||
sum_bitrate = 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Second shifted window.
|
|
||||||
if (frame_cnt >
|
|
||||||
(unsigned int)(rc.window_size + rc.window_size / 2)) {
|
|
||||||
tl = layer_id.temporal_layer_id;
|
|
||||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
|
||||||
sum_bitrate2 += 0.001 * 8.0 * sizes[sl] * framerate;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frame_cnt > (unsigned int)(2 * rc.window_size) &&
|
|
||||||
frame_cnt % rc.window_size == 0) {
|
|
||||||
rc.window_count += 1;
|
|
||||||
rc.avg_st_encoding_bitrate += sum_bitrate2 / rc.window_size;
|
|
||||||
rc.variance_st_encoding_bitrate +=
|
|
||||||
(sum_bitrate2 / rc.window_size) *
|
|
||||||
(sum_bitrate2 / rc.window_size);
|
|
||||||
sum_bitrate2 = 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
printf("SVC frame: %d, kf: %d, size: %d, pts: %d\n", frames_received,
|
|
||||||
!!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY),
|
|
||||||
(int)cx_pkt->data.frame.sz, (int)cx_pkt->data.frame.pts);
|
|
||||||
*/
|
|
||||||
if (enc_cfg.ss_number_layers == 1 && enc_cfg.ts_number_layers == 1)
|
|
||||||
si->bytes_sum[0] += (int)cx_pkt->data.frame.sz;
|
|
||||||
++frames_received;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case VPX_CODEC_STATS_PKT: {
|
|
||||||
stats_write(&app_input.rc_stats, cx_pkt->data.twopass_stats.buf,
|
|
||||||
cx_pkt->data.twopass_stats.sz);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: { break; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!end_of_stream) {
|
|
||||||
++frame_cnt;
|
|
||||||
pts += frame_duration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compensate for the extra frame count for the bypass mode.
|
|
||||||
if (svc_ctx.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
|
|
||||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
|
||||||
const int layer =
|
|
||||||
sl * enc_cfg.ts_number_layers + layer_id.temporal_layer_id;
|
|
||||||
--rc.layer_input_frames[layer];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Processed %d frames\n", frame_cnt);
|
|
||||||
fclose(infile);
|
|
||||||
#if OUTPUT_RC_STATS
|
|
||||||
if (svc_ctx.output_rc_stat) {
|
|
||||||
printout_rate_control_summary(&rc, &enc_cfg, frame_cnt);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
|
|
||||||
if (app_input.passes == 2) stats_close(&app_input.rc_stats, 1);
|
|
||||||
if (writer) {
|
|
||||||
vpx_video_writer_close(writer);
|
|
||||||
}
|
|
||||||
#if OUTPUT_RC_STATS
|
|
||||||
if (svc_ctx.output_rc_stat) {
|
|
||||||
for (tl = 0; tl < enc_cfg.ts_number_layers; ++tl) {
|
|
||||||
vpx_video_writer_close(outfile[tl]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
|
|
||||||
frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000),
|
|
||||||
1000000 * (double)frame_cnt / (double)cx_time);
|
|
||||||
vpx_img_free(&raw);
|
|
||||||
// display average size, psnr
|
|
||||||
printf("%s", vpx_svc_dump_statistics(&svc_ctx));
|
|
||||||
vpx_svc_release(&svc_ctx);
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
@@ -26,27 +26,19 @@
|
|||||||
#include "../tools_common.h"
|
#include "../tools_common.h"
|
||||||
#include "../video_writer.h"
|
#include "../video_writer.h"
|
||||||
|
|
||||||
#define VP8_ROI_MAP 0
|
|
||||||
|
|
||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
|
|
||||||
void usage_exit(void) { exit(EXIT_FAILURE); }
|
void usage_exit(void) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
// Denoiser states for vp8, for temporal denoising.
|
// Denoiser states, for temporal denoising.
|
||||||
enum denoiserStateVp8 {
|
enum denoiserState {
|
||||||
kVp8DenoiserOff,
|
kDenoiserOff,
|
||||||
kVp8DenoiserOnYOnly,
|
kDenoiserOnYOnly,
|
||||||
kVp8DenoiserOnYUV,
|
kDenoiserOnYUV,
|
||||||
kVp8DenoiserOnYUVAggressive,
|
kDenoiserOnYUVAggressive,
|
||||||
kVp8DenoiserOnAdaptive
|
kDenoiserOnAdaptive
|
||||||
};
|
|
||||||
|
|
||||||
// Denoiser states for vp9, for temporal denoising.
|
|
||||||
enum denoiserStateVp9 {
|
|
||||||
kVp9DenoiserOff,
|
|
||||||
kVp9DenoiserOnYOnly,
|
|
||||||
// For SVC: denoise the top two spatial layers.
|
|
||||||
kVp9DenoiserOnYTwoSpatialLayers
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int mode_to_num_layers[13] = {1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3, 3};
|
static int mode_to_num_layers[13] = {1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3, 3};
|
||||||
@@ -94,13 +86,13 @@ static void set_rate_control_metrics(struct RateControlMetrics *rc,
|
|||||||
// per-frame-bandwidth, for the rate control encoding stats below.
|
// per-frame-bandwidth, for the rate control encoding stats below.
|
||||||
const double framerate = cfg->g_timebase.den / cfg->g_timebase.num;
|
const double framerate = cfg->g_timebase.den / cfg->g_timebase.num;
|
||||||
rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0];
|
rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0];
|
||||||
rc->layer_pfb[0] =
|
rc->layer_pfb[0] = 1000.0 * rc->layer_target_bitrate[0] /
|
||||||
1000.0 * rc->layer_target_bitrate[0] / rc->layer_framerate[0];
|
rc->layer_framerate[0];
|
||||||
for (i = 0; i < cfg->ts_number_layers; ++i) {
|
for (i = 0; i < cfg->ts_number_layers; ++i) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i];
|
rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i];
|
||||||
rc->layer_pfb[i] = 1000.0 * (rc->layer_target_bitrate[i] -
|
rc->layer_pfb[i] = 1000.0 *
|
||||||
rc->layer_target_bitrate[i - 1]) /
|
(rc->layer_target_bitrate[i] - rc->layer_target_bitrate[i - 1]) /
|
||||||
(rc->layer_framerate[i] - rc->layer_framerate[i - 1]);
|
(rc->layer_framerate[i] - rc->layer_framerate[i - 1]);
|
||||||
}
|
}
|
||||||
rc->layer_input_frames[i] = 0;
|
rc->layer_input_frames[i] = 0;
|
||||||
@@ -126,27 +118,25 @@ static void printout_rate_control_summary(struct RateControlMetrics *rc,
|
|||||||
printf("Rate control layer stats for %d layer(s):\n\n",
|
printf("Rate control layer stats for %d layer(s):\n\n",
|
||||||
cfg->ts_number_layers);
|
cfg->ts_number_layers);
|
||||||
for (i = 0; i < cfg->ts_number_layers; ++i) {
|
for (i = 0; i < cfg->ts_number_layers; ++i) {
|
||||||
const int num_dropped =
|
const int num_dropped = (i > 0) ?
|
||||||
(i > 0) ? (rc->layer_input_frames[i] - rc->layer_enc_frames[i])
|
(rc->layer_input_frames[i] - rc->layer_enc_frames[i]) :
|
||||||
: (rc->layer_input_frames[i] - rc->layer_enc_frames[i] - 1);
|
(rc->layer_input_frames[i] - rc->layer_enc_frames[i] - 1);
|
||||||
tot_num_frames += rc->layer_input_frames[i];
|
tot_num_frames += rc->layer_input_frames[i];
|
||||||
rc->layer_encoding_bitrate[i] = 0.001 * rc->layer_framerate[i] *
|
rc->layer_encoding_bitrate[i] = 0.001 * rc->layer_framerate[i] *
|
||||||
rc->layer_encoding_bitrate[i] /
|
rc->layer_encoding_bitrate[i] / tot_num_frames;
|
||||||
tot_num_frames;
|
rc->layer_avg_frame_size[i] = rc->layer_avg_frame_size[i] /
|
||||||
rc->layer_avg_frame_size[i] =
|
rc->layer_enc_frames[i];
|
||||||
rc->layer_avg_frame_size[i] / rc->layer_enc_frames[i];
|
rc->layer_avg_rate_mismatch[i] = 100.0 * rc->layer_avg_rate_mismatch[i] /
|
||||||
rc->layer_avg_rate_mismatch[i] =
|
rc->layer_enc_frames[i];
|
||||||
100.0 * rc->layer_avg_rate_mismatch[i] / rc->layer_enc_frames[i];
|
|
||||||
printf("For layer#: %d \n", i);
|
printf("For layer#: %d \n", i);
|
||||||
printf("Bitrate (target vs actual): %d %f \n", rc->layer_target_bitrate[i],
|
printf("Bitrate (target vs actual): %d %f \n", rc->layer_target_bitrate[i],
|
||||||
rc->layer_encoding_bitrate[i]);
|
rc->layer_encoding_bitrate[i]);
|
||||||
printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i],
|
printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i],
|
||||||
rc->layer_avg_frame_size[i]);
|
rc->layer_avg_frame_size[i]);
|
||||||
printf("Average rate_mismatch: %f \n", rc->layer_avg_rate_mismatch[i]);
|
printf("Average rate_mismatch: %f \n", rc->layer_avg_rate_mismatch[i]);
|
||||||
printf(
|
printf("Number of input frames, encoded (non-key) frames, "
|
||||||
"Number of input frames, encoded (non-key) frames, "
|
"and perc dropped frames: %d %d %f \n", rc->layer_input_frames[i],
|
||||||
"and perc dropped frames: %d %d %f \n",
|
rc->layer_enc_frames[i],
|
||||||
rc->layer_input_frames[i], rc->layer_enc_frames[i],
|
|
||||||
100.0 * num_dropped / rc->layer_input_frames[i]);
|
100.0 * num_dropped / rc->layer_input_frames[i]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
@@ -158,59 +148,13 @@ static void printout_rate_control_summary(struct RateControlMetrics *rc,
|
|||||||
rc->avg_st_encoding_bitrate;
|
rc->avg_st_encoding_bitrate;
|
||||||
printf("Short-time stats, for window of %d frames: \n",rc->window_size);
|
printf("Short-time stats, for window of %d frames: \n",rc->window_size);
|
||||||
printf("Average, rms-variance, and percent-fluct: %f %f %f \n",
|
printf("Average, rms-variance, and percent-fluct: %f %f %f \n",
|
||||||
rc->avg_st_encoding_bitrate, sqrt(rc->variance_st_encoding_bitrate),
|
rc->avg_st_encoding_bitrate,
|
||||||
|
sqrt(rc->variance_st_encoding_bitrate),
|
||||||
perc_fluctuation);
|
perc_fluctuation);
|
||||||
if ((frame_cnt - 1) != tot_num_frames)
|
if ((frame_cnt - 1) != tot_num_frames)
|
||||||
die("Error: Number of input frames not equal to output! \n");
|
die("Error: Number of input frames not equal to output! \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if VP8_ROI_MAP
|
|
||||||
static void vp8_set_roi_map(vpx_codec_enc_cfg_t *cfg, vpx_roi_map_t *roi) {
|
|
||||||
unsigned int i, j;
|
|
||||||
memset(roi, 0, sizeof(*roi));
|
|
||||||
|
|
||||||
// ROI is based on the segments (4 for vp8, 8 for vp9), smallest unit for
|
|
||||||
// segment is 16x16 for vp8, 8x8 for vp9.
|
|
||||||
roi->rows = (cfg->g_h + 15) / 16;
|
|
||||||
roi->cols = (cfg->g_w + 15) / 16;
|
|
||||||
|
|
||||||
// Applies delta QP on the segment blocks, varies from -63 to 63.
|
|
||||||
// Setting to negative means lower QP (better quality).
|
|
||||||
// Below we set delta_q to the extreme (-63) to show strong effect.
|
|
||||||
roi->delta_q[0] = 0;
|
|
||||||
roi->delta_q[1] = -63;
|
|
||||||
roi->delta_q[2] = 0;
|
|
||||||
roi->delta_q[3] = 0;
|
|
||||||
|
|
||||||
// Applies delta loopfilter strength on the segment blocks, varies from -63 to
|
|
||||||
// 63. Setting to positive means stronger loopfilter.
|
|
||||||
roi->delta_lf[0] = 0;
|
|
||||||
roi->delta_lf[1] = 0;
|
|
||||||
roi->delta_lf[2] = 0;
|
|
||||||
roi->delta_lf[3] = 0;
|
|
||||||
|
|
||||||
// Applies skip encoding threshold on the segment blocks, varies from 0 to
|
|
||||||
// UINT_MAX. Larger value means more skipping of encoding is possible.
|
|
||||||
// This skip threshold only applies on delta frames.
|
|
||||||
roi->static_threshold[0] = 0;
|
|
||||||
roi->static_threshold[1] = 0;
|
|
||||||
roi->static_threshold[2] = 0;
|
|
||||||
roi->static_threshold[3] = 0;
|
|
||||||
|
|
||||||
// Use 2 states: 1 is center square, 0 is the rest.
|
|
||||||
roi->roi_map =
|
|
||||||
(uint8_t *)calloc(roi->rows * roi->cols, sizeof(*roi->roi_map));
|
|
||||||
for (i = 0; i < roi->rows; ++i) {
|
|
||||||
for (j = 0; j < roi->cols; ++j) {
|
|
||||||
if (i > (roi->rows >> 2) && i < ((roi->rows * 3) >> 2) &&
|
|
||||||
j > (roi->cols >> 2) && j < ((roi->cols * 3) >> 2)) {
|
|
||||||
roi->roi_map[i * roi->cols + j] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Temporal scaling parameters:
|
// Temporal scaling parameters:
|
||||||
// NOTE: The 3 prediction frames cannot be used interchangeably due to
|
// NOTE: The 3 prediction frames cannot be used interchangeably due to
|
||||||
// differences in the way they are handled throughout the code. The
|
// differences in the way they are handled throughout the code. The
|
||||||
@@ -230,8 +174,8 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
cfg->ts_rate_decimator[0] = 1;
|
cfg->ts_rate_decimator[0] = 1;
|
||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
// Update L only.
|
// Update L only.
|
||||||
layer_flags[0] =
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
|
||||||
VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: {
|
case 1: {
|
||||||
@@ -246,15 +190,13 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
#if 1
|
#if 1
|
||||||
// 0=L, 1=GF, Intra-layer prediction enabled.
|
// 0=L, 1=GF, Intra-layer prediction enabled.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF |
|
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
|
||||||
|
layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_REF_ARF;
|
VP8_EFLAG_NO_REF_ARF;
|
||||||
layer_flags[1] =
|
|
||||||
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_REF_ARF;
|
|
||||||
#else
|
#else
|
||||||
// 0=L, 1=GF, Intra-layer prediction disabled.
|
// 0=L, 1=GF, Intra-layer prediction disabled.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF |
|
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
|
||||||
VP8_EFLAG_NO_REF_ARF;
|
|
||||||
layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_LAST;
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_LAST;
|
||||||
#endif
|
#endif
|
||||||
@@ -271,11 +213,10 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
// 0=L, 1=GF, Intra-layer prediction enabled.
|
// 0=L, 1=GF, Intra-layer prediction enabled.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
layer_flags[1] =
|
||||||
layer_flags[1] = layer_flags[2] =
|
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
||||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF |
|
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||||
VP8_EFLAG_NO_UPD_LAST;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3: {
|
case 3: {
|
||||||
@@ -290,12 +231,13 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled.
|
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF |
|
||||||
layer_flags[3] =
|
VP8_EFLAG_NO_UPD_LAST;
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
layer_flags[1] =
|
||||||
layer_flags[1] = layer_flags[2] = layer_flags[4] = layer_flags[5] =
|
layer_flags[2] =
|
||||||
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
|
layer_flags[4] =
|
||||||
|
layer_flags[5] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 4: {
|
case 4: {
|
||||||
@@ -310,13 +252,12 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
// 0=L, 1=GF, 2=ARF, Intra-layer prediction disabled.
|
// 0=L, 1=GF, 2=ARF, Intra-layer prediction disabled.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
||||||
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||||
layer_flags[1] = layer_flags[3] =
|
layer_flags[1] =
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
|
layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 5: {
|
case 5: {
|
||||||
@@ -332,13 +273,12 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled in layer 1, disabled
|
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled in layer 1, disabled
|
||||||
// in layer 2.
|
// in layer 2.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
layer_flags[2] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
layer_flags[2] =
|
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
layer_flags[1] = layer_flags[3] =
|
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
|
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
|
layer_flags[1] =
|
||||||
|
layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
|
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 6: {
|
case 6: {
|
||||||
@@ -353,12 +293,11 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled.
|
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
|
layer_flags[2] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
layer_flags[2] =
|
layer_flags[1] =
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
|
layer_flags[3] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
||||||
layer_flags[1] = layer_flags[3] =
|
|
||||||
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 7: {
|
case 7: {
|
||||||
@@ -375,14 +314,21 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
cfg->ts_rate_decimator[4] = 1;
|
cfg->ts_rate_decimator[4] = 1;
|
||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF;
|
layer_flags[0] = VPX_EFLAG_FORCE_KF;
|
||||||
layer_flags[1] = layer_flags[3] = layer_flags[5] = layer_flags[7] =
|
layer_flags[1] =
|
||||||
layer_flags[9] = layer_flags[11] = layer_flags[13] = layer_flags[15] =
|
layer_flags[3] =
|
||||||
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
|
layer_flags[5] =
|
||||||
|
layer_flags[7] =
|
||||||
|
layer_flags[9] =
|
||||||
|
layer_flags[11] =
|
||||||
|
layer_flags[13] =
|
||||||
|
layer_flags[15] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
layer_flags[2] = layer_flags[6] = layer_flags[10] = layer_flags[14] =
|
layer_flags[2] =
|
||||||
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_GF;
|
layer_flags[6] =
|
||||||
layer_flags[4] = layer_flags[12] =
|
layer_flags[10] =
|
||||||
VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_ARF;
|
layer_flags[14] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_GF;
|
||||||
|
layer_flags[4] =
|
||||||
|
layer_flags[12] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_ARF;
|
||||||
layer_flags[8] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF;
|
layer_flags[8] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -400,14 +346,14 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
// key frame. Sync point every 8 frames.
|
// key frame. Sync point every 8 frames.
|
||||||
|
|
||||||
// Layer 0: predict from L and ARF, update L and G.
|
// Layer 0: predict from L and ARF, update L and G.
|
||||||
layer_flags[0] =
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
||||||
VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
// Layer 1: sync point: predict from L and ARF, and update G.
|
// Layer 1: sync point: predict from L and ARF, and update G.
|
||||||
layer_flags[1] =
|
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
// Layer 0, predict from L and ARF, update L.
|
// Layer 0, predict from L and ARF, update L.
|
||||||
layer_flags[2] =
|
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
// Layer 1: predict from L, G and ARF, and update G.
|
// Layer 1: predict from L, G and ARF, and update G.
|
||||||
layer_flags[3] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
layer_flags[3] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_UPD_ENTROPY;
|
VP8_EFLAG_NO_UPD_ENTROPY;
|
||||||
@@ -433,18 +379,17 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
// 0=L, 1=GF, 2=ARF.
|
// 0=L, 1=GF, 2=ARF.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
||||||
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
||||||
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
||||||
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
|
||||||
layer_flags[3] = layer_flags[5] =
|
layer_flags[3] =
|
||||||
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
layer_flags[5] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
||||||
layer_flags[4] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
layer_flags[4] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
||||||
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
layer_flags[6] =
|
layer_flags[6] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
layer_flags[7] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
|
layer_flags[7] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_ENTROPY;
|
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_ENTROPY;
|
||||||
break;
|
break;
|
||||||
@@ -464,21 +409,21 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
// 0=L, 1=GF, 2=ARF.
|
// 0=L, 1=GF, 2=ARF.
|
||||||
// Layer 0: predict from L and ARF; update L and G.
|
// Layer 0: predict from L and ARF; update L and G.
|
||||||
layer_flags[0] =
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_ARF |
|
||||||
VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
|
VP8_EFLAG_NO_REF_GF;
|
||||||
// Layer 2: sync point: predict from L and ARF; update none.
|
// Layer 2: sync point: predict from L and ARF; update none.
|
||||||
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
|
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_UPD_ENTROPY;
|
VP8_EFLAG_NO_UPD_ENTROPY;
|
||||||
// Layer 1: sync point: predict from L and ARF; update G.
|
// Layer 1: sync point: predict from L and ARF; update G.
|
||||||
layer_flags[2] =
|
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF |
|
||||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
VP8_EFLAG_NO_UPD_LAST;
|
||||||
// Layer 2: predict from L, G, ARF; update none.
|
// Layer 2: predict from L, G, ARF; update none.
|
||||||
layer_flags[3] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
|
layer_flags[3] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
|
||||||
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY;
|
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY;
|
||||||
// Layer 0: predict from L and ARF; update L.
|
// Layer 0: predict from L and ARF; update L.
|
||||||
layer_flags[4] =
|
layer_flags[4] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
|
||||||
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
|
VP8_EFLAG_NO_REF_GF;
|
||||||
// Layer 2: predict from L, G, ARF; update none.
|
// Layer 2: predict from L, G, ARF; update none.
|
||||||
layer_flags[5] = layer_flags[3];
|
layer_flags[5] = layer_flags[3];
|
||||||
// Layer 1: predict from L, G, ARF; update G.
|
// Layer 1: predict from L, G, ARF; update G.
|
||||||
@@ -526,8 +471,8 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
// 0=L, 1=GF, 2=ARF.
|
// 0=L, 1=GF, 2=ARF.
|
||||||
// Layer 0: predict from L and ARF; update L.
|
// Layer 0: predict from L and ARF; update L.
|
||||||
layer_flags[0] =
|
layer_flags[0] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
|
||||||
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
|
VP8_EFLAG_NO_REF_GF;
|
||||||
layer_flags[4] = layer_flags[0];
|
layer_flags[4] = layer_flags[0];
|
||||||
// Layer 1: predict from L, G, ARF; update G.
|
// Layer 1: predict from L, G, ARF; update G.
|
||||||
layer_flags[2] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
layer_flags[2] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||||
@@ -552,7 +497,6 @@ int main(int argc, char **argv) {
|
|||||||
vpx_codec_err_t res;
|
vpx_codec_err_t res;
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
uint32_t error_resilient = 0;
|
|
||||||
int speed;
|
int speed;
|
||||||
int frame_avail;
|
int frame_avail;
|
||||||
int got_data;
|
int got_data;
|
||||||
@@ -563,22 +507,23 @@ int main(int argc, char **argv) {
|
|||||||
int layering_mode = 0;
|
int layering_mode = 0;
|
||||||
int layer_flags[VPX_TS_MAX_PERIODICITY] = {0};
|
int layer_flags[VPX_TS_MAX_PERIODICITY] = {0};
|
||||||
int flag_periodicity = 1;
|
int flag_periodicity = 1;
|
||||||
#if VP8_ROI_MAP
|
#if VPX_ENCODER_ABI_VERSION > (4 + VPX_CODEC_ABI_VERSION)
|
||||||
vpx_roi_map_t roi;
|
|
||||||
#endif
|
|
||||||
vpx_svc_layer_id_t layer_id = {0, 0};
|
vpx_svc_layer_id_t layer_id = {0, 0};
|
||||||
|
#else
|
||||||
|
vpx_svc_layer_id_t layer_id = {0};
|
||||||
|
#endif
|
||||||
const VpxInterface *encoder = NULL;
|
const VpxInterface *encoder = NULL;
|
||||||
FILE *infile = NULL;
|
FILE *infile = NULL;
|
||||||
struct RateControlMetrics rc;
|
struct RateControlMetrics rc;
|
||||||
int64_t cx_time = 0;
|
int64_t cx_time = 0;
|
||||||
const int min_args_base = 13;
|
const int min_args_base = 11;
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
vpx_bit_depth_t bit_depth = VPX_BITS_8;
|
vpx_bit_depth_t bit_depth = VPX_BITS_8;
|
||||||
int input_bit_depth = 8;
|
int input_bit_depth = 8;
|
||||||
const int min_args = min_args_base + 1;
|
const int min_args = min_args_base + 1;
|
||||||
#else
|
#else
|
||||||
const int min_args = min_args_base;
|
const int min_args = min_args_base;
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
double sum_bitrate = 0.0;
|
double sum_bitrate = 0.0;
|
||||||
double sum_bitrate2 = 0.0;
|
double sum_bitrate2 = 0.0;
|
||||||
double framerate = 30.0;
|
double framerate = 30.0;
|
||||||
@@ -586,42 +531,39 @@ int main(int argc, char **argv) {
|
|||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
// Check usage and arguments.
|
// Check usage and arguments.
|
||||||
if (argc < min_args) {
|
if (argc < min_args) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
||||||
"<rate_num> <rate_den> <speed> <frame_drop_threshold> "
|
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> "
|
||||||
"<error_resilient> <threads> <mode> "
|
"<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n", argv[0]);
|
||||||
"<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n",
|
|
||||||
argv[0]);
|
|
||||||
#else
|
#else
|
||||||
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
||||||
"<rate_num> <rate_den> <speed> <frame_drop_threshold> "
|
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> "
|
||||||
"<error_resilient> <threads> <mode> "
|
"<Rate_0> ... <Rate_nlayers-1> \n", argv[0]);
|
||||||
"<Rate_0> ... <Rate_nlayers-1> \n",
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
argv[0]);
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
}
|
}
|
||||||
|
|
||||||
encoder = get_vpx_encoder_by_name(argv[3]);
|
encoder = get_vpx_encoder_by_name(argv[3]);
|
||||||
if (!encoder) die("Unsupported codec.");
|
if (!encoder)
|
||||||
|
die("Unsupported codec.");
|
||||||
|
|
||||||
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
||||||
|
|
||||||
width = (unsigned int)strtoul(argv[4], NULL, 0);
|
width = strtol(argv[4], NULL, 0);
|
||||||
height = (unsigned int)strtoul(argv[5], NULL, 0);
|
height = strtol(argv[5], NULL, 0);
|
||||||
if (width < 16 || width % 2 || height < 16 || height % 2) {
|
if (width < 16 || width % 2 || height < 16 || height % 2) {
|
||||||
die("Invalid resolution: %d x %d", width, height);
|
die("Invalid resolution: %d x %d", width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
layering_mode = (int)strtol(argv[12], NULL, 0);
|
layering_mode = strtol(argv[10], NULL, 0);
|
||||||
if (layering_mode < 0 || layering_mode > 13) {
|
if (layering_mode < 0 || layering_mode > 13) {
|
||||||
die("Invalid layering mode (0..12) %s", argv[12]);
|
die("Invalid layering mode (0..12) %s", argv[10]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc != min_args + mode_to_num_layers[layering_mode]) {
|
if (argc != min_args + mode_to_num_layers[layering_mode]) {
|
||||||
die("Invalid number of arguments");
|
die("Invalid number of arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
switch (strtol(argv[argc-1], NULL, 0)) {
|
switch (strtol(argv[argc-1], NULL, 0)) {
|
||||||
case 8:
|
case 8:
|
||||||
bit_depth = VPX_BITS_8;
|
bit_depth = VPX_BITS_8;
|
||||||
@@ -635,10 +577,12 @@ int main(int argc, char **argv) {
|
|||||||
bit_depth = VPX_BITS_12;
|
bit_depth = VPX_BITS_12;
|
||||||
input_bit_depth = 12;
|
input_bit_depth = 12;
|
||||||
break;
|
break;
|
||||||
default: die("Invalid bit depth (8, 10, 12) %s", argv[argc - 1]);
|
default:
|
||||||
|
die("Invalid bit depth (8, 10, 12) %s", argv[argc-1]);
|
||||||
}
|
}
|
||||||
if (!vpx_img_alloc(
|
if (!vpx_img_alloc(&raw,
|
||||||
&raw, bit_depth == VPX_BITS_8 ? VPX_IMG_FMT_I420 : VPX_IMG_FMT_I42016,
|
bit_depth == VPX_BITS_8 ? VPX_IMG_FMT_I420 :
|
||||||
|
VPX_IMG_FMT_I42016,
|
||||||
width, height, 32)) {
|
width, height, 32)) {
|
||||||
die("Failed to allocate image", width, height);
|
die("Failed to allocate image", width, height);
|
||||||
}
|
}
|
||||||
@@ -646,7 +590,7 @@ int main(int argc, char **argv) {
|
|||||||
if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 32)) {
|
if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 32)) {
|
||||||
die("Failed to allocate image", width, height);
|
die("Failed to allocate image", width, height);
|
||||||
}
|
}
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
|
||||||
// Populate encoder configuration.
|
// Populate encoder configuration.
|
||||||
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
||||||
@@ -659,41 +603,43 @@ int main(int argc, char **argv) {
|
|||||||
cfg.g_w = width;
|
cfg.g_w = width;
|
||||||
cfg.g_h = height;
|
cfg.g_h = height;
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
if (bit_depth != VPX_BITS_8) {
|
if (bit_depth != VPX_BITS_8) {
|
||||||
cfg.g_bit_depth = bit_depth;
|
cfg.g_bit_depth = bit_depth;
|
||||||
cfg.g_input_bit_depth = input_bit_depth;
|
cfg.g_input_bit_depth = input_bit_depth;
|
||||||
cfg.g_profile = 2;
|
cfg.g_profile = 2;
|
||||||
}
|
}
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
|
||||||
// Timebase format e.g. 30fps: numerator=1, demoninator = 30.
|
// Timebase format e.g. 30fps: numerator=1, demoninator = 30.
|
||||||
cfg.g_timebase.num = (int)strtol(argv[6], NULL, 0);
|
cfg.g_timebase.num = strtol(argv[6], NULL, 0);
|
||||||
cfg.g_timebase.den = (int)strtol(argv[7], NULL, 0);
|
cfg.g_timebase.den = strtol(argv[7], NULL, 0);
|
||||||
|
|
||||||
speed = (int)strtol(argv[8], NULL, 0);
|
speed = strtol(argv[8], NULL, 0);
|
||||||
if (speed < 0) {
|
if (speed < 0) {
|
||||||
die("Invalid speed setting: must be positive");
|
die("Invalid speed setting: must be positive");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = min_args_base;
|
for (i = min_args_base;
|
||||||
(int)i < min_args_base + mode_to_num_layers[layering_mode]; ++i) {
|
(int)i < min_args_base + mode_to_num_layers[layering_mode];
|
||||||
rc.layer_target_bitrate[i - 13] = (int)strtol(argv[i], NULL, 0);
|
++i) {
|
||||||
|
rc.layer_target_bitrate[i - 11] = strtol(argv[i], NULL, 0);
|
||||||
if (strncmp(encoder->name, "vp8", 3) == 0)
|
if (strncmp(encoder->name, "vp8", 3) == 0)
|
||||||
cfg.ts_target_bitrate[i - 13] = rc.layer_target_bitrate[i - 13];
|
cfg.ts_target_bitrate[i - 11] = rc.layer_target_bitrate[i - 11];
|
||||||
else if (strncmp(encoder->name, "vp9", 3) == 0)
|
else if (strncmp(encoder->name, "vp9", 3) == 0)
|
||||||
cfg.layer_target_bitrate[i - 13] = rc.layer_target_bitrate[i - 13];
|
cfg.layer_target_bitrate[i - 11] = rc.layer_target_bitrate[i - 11];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Real time parameters.
|
// Real time parameters.
|
||||||
cfg.rc_dropframe_thresh = (unsigned int)strtoul(argv[9], NULL, 0);
|
cfg.rc_dropframe_thresh = strtol(argv[9], NULL, 0);
|
||||||
cfg.rc_end_usage = VPX_CBR;
|
cfg.rc_end_usage = VPX_CBR;
|
||||||
cfg.rc_min_quantizer = 2;
|
cfg.rc_min_quantizer = 2;
|
||||||
cfg.rc_max_quantizer = 56;
|
cfg.rc_max_quantizer = 56;
|
||||||
if (strncmp(encoder->name, "vp9", 3) == 0) cfg.rc_max_quantizer = 52;
|
if (strncmp(encoder->name, "vp9", 3) == 0)
|
||||||
|
cfg.rc_max_quantizer = 52;
|
||||||
cfg.rc_undershoot_pct = 50;
|
cfg.rc_undershoot_pct = 50;
|
||||||
cfg.rc_overshoot_pct = 50;
|
cfg.rc_overshoot_pct = 50;
|
||||||
cfg.rc_buf_initial_sz = 600;
|
cfg.rc_buf_initial_sz = 500;
|
||||||
cfg.rc_buf_optimal_sz = 600;
|
cfg.rc_buf_optimal_sz = 600;
|
||||||
cfg.rc_buf_sz = 1000;
|
cfg.rc_buf_sz = 1000;
|
||||||
|
|
||||||
@@ -701,14 +647,10 @@ int main(int argc, char **argv) {
|
|||||||
cfg.rc_resize_allowed = 0;
|
cfg.rc_resize_allowed = 0;
|
||||||
|
|
||||||
// Use 1 thread as default.
|
// Use 1 thread as default.
|
||||||
cfg.g_threads = (unsigned int)strtoul(argv[11], NULL, 0);
|
cfg.g_threads = 1;
|
||||||
|
|
||||||
error_resilient = (uint32_t)strtoul(argv[10], NULL, 0);
|
|
||||||
if (error_resilient != 0 && error_resilient != 1) {
|
|
||||||
die("Invalid value for error resilient (0, 1): %d.", error_resilient);
|
|
||||||
}
|
|
||||||
// Enable error resilient mode.
|
// Enable error resilient mode.
|
||||||
cfg.g_error_resilient = error_resilient;
|
cfg.g_error_resilient = 1;
|
||||||
cfg.g_lag_in_frames = 0;
|
cfg.g_lag_in_frames = 0;
|
||||||
cfg.kf_mode = VPX_KF_AUTO;
|
cfg.kf_mode = VPX_KF_AUTO;
|
||||||
|
|
||||||
@@ -717,7 +659,9 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
|
cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
|
||||||
|
|
||||||
set_temporal_layer_pattern(layering_mode, &cfg, layer_flags,
|
set_temporal_layer_pattern(layering_mode,
|
||||||
|
&cfg,
|
||||||
|
layer_flags,
|
||||||
&flag_periodicity);
|
&flag_periodicity);
|
||||||
|
|
||||||
set_rate_control_metrics(&rc, &cfg);
|
set_rate_control_metrics(&rc, &cfg);
|
||||||
@@ -744,7 +688,8 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
snprintf(file_name, sizeof(file_name), "%s_%d.ivf", argv[2], i);
|
snprintf(file_name, sizeof(file_name), "%s_%d.ivf", argv[2], i);
|
||||||
outfile[i] = vpx_video_writer_open(file_name, kContainerIVF, &info);
|
outfile[i] = vpx_video_writer_open(file_name, kContainerIVF, &info);
|
||||||
if (!outfile[i]) die("Failed to open %s for writing", file_name);
|
if (!outfile[i])
|
||||||
|
die("Failed to open %s for writing", file_name);
|
||||||
|
|
||||||
assert(outfile[i] != NULL);
|
assert(outfile[i] != NULL);
|
||||||
}
|
}
|
||||||
@@ -752,44 +697,28 @@ int main(int argc, char **argv) {
|
|||||||
cfg.ss_number_layers = 1;
|
cfg.ss_number_layers = 1;
|
||||||
|
|
||||||
// Initialize codec.
|
// Initialize codec.
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
if (vpx_codec_enc_init(
|
if (vpx_codec_enc_init(
|
||||||
&codec, encoder->codec_interface(), &cfg,
|
&codec, encoder->codec_interface(), &cfg,
|
||||||
bit_depth == VPX_BITS_8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH))
|
bit_depth == VPX_BITS_8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH))
|
||||||
#else
|
#else
|
||||||
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
|
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
die_codec(&codec, "Failed to initialize encoder");
|
die_codec(&codec, "Failed to initialize encoder");
|
||||||
|
|
||||||
if (strncmp(encoder->name, "vp8", 3) == 0) {
|
if (strncmp(encoder->name, "vp8", 3) == 0) {
|
||||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
|
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
|
||||||
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kVp8DenoiserOff);
|
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOff);
|
||||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||||
vpx_codec_control(&codec, VP8E_SET_GF_CBR_BOOST_PCT, 0);
|
|
||||||
#if VP8_ROI_MAP
|
|
||||||
vp8_set_roi_map(&cfg, &roi);
|
|
||||||
if (vpx_codec_control(&codec, VP8E_SET_ROI_MAP, &roi))
|
|
||||||
die_codec(&codec, "Failed to set ROI map");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} else if (strncmp(encoder->name, "vp9", 3) == 0) {
|
} else if (strncmp(encoder->name, "vp9", 3) == 0) {
|
||||||
vpx_svc_extra_cfg_t svc_params;
|
vpx_svc_extra_cfg_t svc_params;
|
||||||
memset(&svc_params, 0, sizeof(svc_params));
|
|
||||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed);
|
vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed);
|
||||||
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
|
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
|
||||||
vpx_codec_control(&codec, VP9E_SET_GF_CBR_BOOST_PCT, 0);
|
|
||||||
vpx_codec_control(&codec, VP9E_SET_FRAME_PARALLEL_DECODING, 0);
|
|
||||||
vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0);
|
vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0);
|
||||||
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kVp9DenoiserOff);
|
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kDenoiserOff);
|
||||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||||
vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);
|
vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);
|
||||||
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (cfg.g_threads >> 1));
|
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (cfg.g_threads >> 1));
|
||||||
// TODO(marpan/jianj): There is an issue with row-mt for low resolutons at
|
|
||||||
// high speed settings, disable its use for those cases for now.
|
|
||||||
if (cfg.g_threads > 1 && ((cfg.g_w > 320 && cfg.g_h > 240) || speed < 7))
|
|
||||||
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 1);
|
|
||||||
else
|
|
||||||
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 0);
|
|
||||||
if (vpx_codec_control(&codec, VP9E_SET_SVC, layering_mode > 0 ? 1: 0))
|
if (vpx_codec_control(&codec, VP9E_SET_SVC, layering_mode > 0 ? 1: 0))
|
||||||
die_codec(&codec, "Failed to set SVC");
|
die_codec(&codec, "Failed to set SVC");
|
||||||
for (i = 0; i < cfg.ts_number_layers; ++i) {
|
for (i = 0; i < cfg.ts_number_layers; ++i) {
|
||||||
@@ -808,7 +737,7 @@ int main(int argc, char **argv) {
|
|||||||
// For generating smaller key frames, use a smaller max_intra_size_pct
|
// For generating smaller key frames, use a smaller max_intra_size_pct
|
||||||
// value, like 100 or 200.
|
// value, like 100 or 200.
|
||||||
{
|
{
|
||||||
const int max_intra_size_pct = 1000;
|
const int max_intra_size_pct = 900;
|
||||||
vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT,
|
vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT,
|
||||||
max_intra_size_pct);
|
max_intra_size_pct);
|
||||||
}
|
}
|
||||||
@@ -818,8 +747,10 @@ int main(int argc, char **argv) {
|
|||||||
struct vpx_usec_timer timer;
|
struct vpx_usec_timer timer;
|
||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
const vpx_codec_cx_pkt_t *pkt;
|
const vpx_codec_cx_pkt_t *pkt;
|
||||||
|
#if VPX_ENCODER_ABI_VERSION > (4 + VPX_CODEC_ABI_VERSION)
|
||||||
// Update the temporal layer_id. No spatial layers in this test.
|
// Update the temporal layer_id. No spatial layers in this test.
|
||||||
layer_id.spatial_layer_id = 0;
|
layer_id.spatial_layer_id = 0;
|
||||||
|
#endif
|
||||||
layer_id.temporal_layer_id =
|
layer_id.temporal_layer_id =
|
||||||
cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
|
cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
|
||||||
if (strncmp(encoder->name, "vp9", 3) == 0) {
|
if (strncmp(encoder->name, "vp9", 3) == 0) {
|
||||||
@@ -829,9 +760,11 @@ int main(int argc, char **argv) {
|
|||||||
layer_id.temporal_layer_id);
|
layer_id.temporal_layer_id);
|
||||||
}
|
}
|
||||||
flags = layer_flags[frame_cnt % flag_periodicity];
|
flags = layer_flags[frame_cnt % flag_periodicity];
|
||||||
if (layering_mode == 0) flags = 0;
|
if (layering_mode == 0)
|
||||||
|
flags = 0;
|
||||||
frame_avail = vpx_img_read(&raw, infile);
|
frame_avail = vpx_img_read(&raw, infile);
|
||||||
if (frame_avail) ++rc.layer_input_frames[layer_id.temporal_layer_id];
|
if (frame_avail)
|
||||||
|
++rc.layer_input_frames[layer_id.temporal_layer_id];
|
||||||
vpx_usec_timer_start(&timer);
|
vpx_usec_timer_start(&timer);
|
||||||
if (vpx_codec_encode(&codec, frame_avail? &raw : NULL, pts, 1, flags,
|
if (vpx_codec_encode(&codec, frame_avail? &raw : NULL, pts, 1, flags,
|
||||||
VPX_DL_REALTIME)) {
|
VPX_DL_REALTIME)) {
|
||||||
@@ -892,7 +825,8 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: break;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++frame_cnt;
|
++frame_cnt;
|
||||||
@@ -902,13 +836,16 @@ int main(int argc, char **argv) {
|
|||||||
printout_rate_control_summary(&rc, &cfg, frame_cnt);
|
printout_rate_control_summary(&rc, &cfg, frame_cnt);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
|
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
|
||||||
frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000),
|
frame_cnt,
|
||||||
|
1000 * (float)cx_time / (double)(frame_cnt * 1000000),
|
||||||
1000000 * (double)frame_cnt / (double)cx_time);
|
1000000 * (double)frame_cnt / (double)cx_time);
|
||||||
|
|
||||||
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
|
if (vpx_codec_destroy(&codec))
|
||||||
|
die_codec(&codec, "Failed to destroy codec");
|
||||||
|
|
||||||
// Try to rewrite the output file headers with the actual frame count.
|
// Try to rewrite the output file headers with the actual frame count.
|
||||||
for (i = 0; i < cfg.ts_number_layers; ++i) vpx_video_writer_close(outfile[i]);
|
for (i = 0; i < cfg.ts_number_layers; ++i)
|
||||||
|
vpx_video_writer_close(outfile[i]);
|
||||||
|
|
||||||
vpx_img_free(&raw);
|
vpx_img_free(&raw);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|||||||
@@ -8,10 +8,11 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// VP9 Set Reference Frame
|
|
||||||
|
// VP10 Set Reference Frame
|
||||||
// ============================
|
// ============================
|
||||||
//
|
//
|
||||||
// This is an example demonstrating how to overwrite the VP9 encoder's
|
// This is an example demonstrating how to overwrite the VP10 encoder's
|
||||||
// internal reference frame. In the sample we set the last frame to the
|
// internal reference frame. In the sample we set the last frame to the
|
||||||
// current frame. This technique could be used to bounce between two cameras.
|
// current frame. This technique could be used to bounce between two cameras.
|
||||||
//
|
//
|
||||||
@@ -24,7 +25,7 @@
|
|||||||
// -----
|
// -----
|
||||||
// This example encodes a raw video. And the last argument passed in specifies
|
// This example encodes a raw video. And the last argument passed in specifies
|
||||||
// the frame number to update the reference frame on. For example, run
|
// the frame number to update the reference frame on. For example, run
|
||||||
// examples/vp9cx_set_ref 352 288 in.yuv out.ivf 4 30
|
// examples/vpx_cx_set_ref vp10 352 288 in.yuv out.ivf 4 30
|
||||||
// The parameter is parsed as follows:
|
// The parameter is parsed as follows:
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@@ -53,7 +54,6 @@
|
|||||||
#include "vpx/vp8cx.h"
|
#include "vpx/vp8cx.h"
|
||||||
#include "vpx/vpx_decoder.h"
|
#include "vpx/vpx_decoder.h"
|
||||||
#include "vpx/vpx_encoder.h"
|
#include "vpx/vpx_encoder.h"
|
||||||
#include "vp9/common/vp9_common.h"
|
|
||||||
|
|
||||||
#include "./tools_common.h"
|
#include "./tools_common.h"
|
||||||
#include "./video_writer.h"
|
#include "./video_writer.h"
|
||||||
@@ -61,8 +61,7 @@
|
|||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
|
|
||||||
void usage_exit() {
|
void usage_exit() {
|
||||||
fprintf(stderr,
|
fprintf(stderr, "Usage: %s <codec> <width> <height> <infile> <outfile> "
|
||||||
"Usage: %s <width> <height> <infile> <outfile> "
|
|
||||||
"<frame> <limit(optional)>\n",
|
"<frame> <limit(optional)>\n",
|
||||||
exec_name);
|
exec_name);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
@@ -71,7 +70,8 @@ void usage_exit() {
|
|||||||
static int compare_img(const vpx_image_t *const img1,
|
static int compare_img(const vpx_image_t *const img1,
|
||||||
const vpx_image_t *const img2) {
|
const vpx_image_t *const img2) {
|
||||||
uint32_t l_w = img1->d_w;
|
uint32_t l_w = img1->d_w;
|
||||||
uint32_t c_w = (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
|
uint32_t c_w =
|
||||||
|
(img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
|
||||||
const uint32_t c_h =
|
const uint32_t c_h =
|
||||||
(img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
|
(img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
@@ -101,8 +101,8 @@ static int compare_img(const vpx_image_t *const img1,
|
|||||||
|
|
||||||
#define mmin(a, b) ((a) < (b) ? (a) : (b))
|
#define mmin(a, b) ((a) < (b) ? (a) : (b))
|
||||||
static void find_mismatch(const vpx_image_t *const img1,
|
static void find_mismatch(const vpx_image_t *const img1,
|
||||||
const vpx_image_t *const img2, int yloc[4],
|
const vpx_image_t *const img2,
|
||||||
int uloc[4], int vloc[4]) {
|
int yloc[4], int uloc[4], int vloc[4]) {
|
||||||
const uint32_t bsize = 64;
|
const uint32_t bsize = 64;
|
||||||
const uint32_t bsizey = bsize >> img1->y_chroma_shift;
|
const uint32_t bsizey = bsize >> img1->y_chroma_shift;
|
||||||
const uint32_t bsizex = bsize >> img1->x_chroma_shift;
|
const uint32_t bsizex = bsize >> img1->x_chroma_shift;
|
||||||
@@ -190,12 +190,16 @@ static void find_mismatch(const vpx_image_t *const img1,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void testing_decode(vpx_codec_ctx_t *encoder, vpx_codec_ctx_t *decoder,
|
static void testing_decode(vpx_codec_ctx_t *encoder,
|
||||||
unsigned int frame_out, int *mismatch_seen) {
|
vpx_codec_ctx_t *decoder,
|
||||||
|
vpx_codec_enc_cfg_t *cfg,
|
||||||
|
unsigned int frame_out,
|
||||||
|
int *mismatch_seen) {
|
||||||
vpx_image_t enc_img, dec_img;
|
vpx_image_t enc_img, dec_img;
|
||||||
struct vp9_ref_frame ref_enc, ref_dec;
|
struct vp9_ref_frame ref_enc, ref_dec;
|
||||||
|
|
||||||
if (*mismatch_seen) return;
|
if (*mismatch_seen)
|
||||||
|
return;
|
||||||
|
|
||||||
ref_enc.idx = 0;
|
ref_enc.idx = 0;
|
||||||
ref_dec.idx = 0;
|
ref_dec.idx = 0;
|
||||||
@@ -212,30 +216,37 @@ static void testing_decode(vpx_codec_ctx_t *encoder, vpx_codec_ctx_t *decoder,
|
|||||||
*mismatch_seen = 1;
|
*mismatch_seen = 1;
|
||||||
|
|
||||||
find_mismatch(&enc_img, &dec_img, y, u, v);
|
find_mismatch(&enc_img, &dec_img, y, u, v);
|
||||||
printf(
|
printf("Encode/decode mismatch on frame %d at"
|
||||||
"Encode/decode mismatch on frame %d at"
|
|
||||||
" Y[%d, %d] {%d/%d},"
|
" Y[%d, %d] {%d/%d},"
|
||||||
" U[%d, %d] {%d/%d},"
|
" U[%d, %d] {%d/%d},"
|
||||||
" V[%d, %d] {%d/%d}",
|
" V[%d, %d] {%d/%d}",
|
||||||
frame_out, y[0], y[1], y[2], y[3], u[0], u[1], u[2], u[3], v[0], v[1],
|
frame_out,
|
||||||
v[2], v[3]);
|
y[0], y[1], y[2], y[3],
|
||||||
|
u[0], u[1], u[2], u[3],
|
||||||
|
v[0], v[1], v[2], v[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_img_free(&enc_img);
|
vpx_img_free(&enc_img);
|
||||||
vpx_img_free(&dec_img);
|
vpx_img_free(&dec_img);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int encode_frame(vpx_codec_ctx_t *ecodec, vpx_image_t *img,
|
static int encode_frame(vpx_codec_ctx_t *ecodec,
|
||||||
unsigned int frame_in, VpxVideoWriter *writer,
|
vpx_codec_enc_cfg_t *cfg,
|
||||||
int test_decode, vpx_codec_ctx_t *dcodec,
|
vpx_image_t *img,
|
||||||
unsigned int *frame_out, int *mismatch_seen) {
|
unsigned int frame_in,
|
||||||
|
VpxVideoWriter *writer,
|
||||||
|
int test_decode,
|
||||||
|
vpx_codec_ctx_t *dcodec,
|
||||||
|
unsigned int *frame_out,
|
||||||
|
int *mismatch_seen) {
|
||||||
int got_pkts = 0;
|
int got_pkts = 0;
|
||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
const vpx_codec_cx_pkt_t *pkt = NULL;
|
const vpx_codec_cx_pkt_t *pkt = NULL;
|
||||||
int got_data;
|
int got_data;
|
||||||
const vpx_codec_err_t res =
|
const vpx_codec_err_t res = vpx_codec_encode(ecodec, img, frame_in, 1,
|
||||||
vpx_codec_encode(ecodec, img, frame_in, 1, 0, VPX_DL_GOOD_QUALITY);
|
0, VPX_DL_GOOD_QUALITY);
|
||||||
if (res != VPX_CODEC_OK) die_codec(ecodec, "Failed to encode frame");
|
if (res != VPX_CODEC_OK)
|
||||||
|
die_codec(ecodec, "Failed to encode frame");
|
||||||
|
|
||||||
got_data = 0;
|
got_data = 0;
|
||||||
|
|
||||||
@@ -249,7 +260,8 @@ static int encode_frame(vpx_codec_ctx_t *ecodec, vpx_image_t *img,
|
|||||||
*frame_out += 1;
|
*frame_out += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf,
|
if (!vpx_video_writer_write_frame(writer,
|
||||||
|
pkt->data.frame.buf,
|
||||||
pkt->data.frame.sz,
|
pkt->data.frame.sz,
|
||||||
pkt->data.frame.pts)) {
|
pkt->data.frame.pts)) {
|
||||||
die_codec(ecodec, "Failed to write compressed frame");
|
die_codec(ecodec, "Failed to write compressed frame");
|
||||||
@@ -269,7 +281,7 @@ static int encode_frame(vpx_codec_ctx_t *ecodec, vpx_image_t *img,
|
|||||||
|
|
||||||
// Mismatch checking
|
// Mismatch checking
|
||||||
if (got_data && test_decode) {
|
if (got_data && test_decode) {
|
||||||
testing_decode(ecodec, dcodec, *frame_out, mismatch_seen);
|
testing_decode(ecodec, dcodec, cfg, *frame_out, mismatch_seen);
|
||||||
}
|
}
|
||||||
|
|
||||||
return got_pkts;
|
return got_pkts;
|
||||||
@@ -278,12 +290,12 @@ static int encode_frame(vpx_codec_ctx_t *ecodec, vpx_image_t *img,
|
|||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
FILE *infile = NULL;
|
FILE *infile = NULL;
|
||||||
// Encoder
|
// Encoder
|
||||||
vpx_codec_ctx_t ecodec;
|
vpx_codec_ctx_t ecodec = {0};
|
||||||
vpx_codec_enc_cfg_t cfg;
|
vpx_codec_enc_cfg_t cfg = {0};
|
||||||
unsigned int frame_in = 0;
|
unsigned int frame_in = 0;
|
||||||
vpx_image_t raw;
|
vpx_image_t raw;
|
||||||
vpx_codec_err_t res;
|
vpx_codec_err_t res;
|
||||||
VpxVideoInfo info;
|
VpxVideoInfo info = {0};
|
||||||
VpxVideoWriter *writer = NULL;
|
VpxVideoWriter *writer = NULL;
|
||||||
const VpxInterface *encoder = NULL;
|
const VpxInterface *encoder = NULL;
|
||||||
|
|
||||||
@@ -300,52 +312,50 @@ int main(int argc, char **argv) {
|
|||||||
const int fps = 30;
|
const int fps = 30;
|
||||||
const int bitrate = 500;
|
const int bitrate = 500;
|
||||||
|
|
||||||
|
const char *codec_arg = NULL;
|
||||||
const char *width_arg = NULL;
|
const char *width_arg = NULL;
|
||||||
const char *height_arg = NULL;
|
const char *height_arg = NULL;
|
||||||
const char *infile_arg = NULL;
|
const char *infile_arg = NULL;
|
||||||
const char *outfile_arg = NULL;
|
const char *outfile_arg = NULL;
|
||||||
const char *update_frame_num_arg = NULL;
|
|
||||||
unsigned int limit = 0;
|
unsigned int limit = 0;
|
||||||
|
|
||||||
vp9_zero(ecodec);
|
|
||||||
vp9_zero(cfg);
|
|
||||||
vp9_zero(info);
|
|
||||||
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc < 6) die("Invalid number of arguments");
|
if (argc < 7)
|
||||||
|
die("Invalid number of arguments");
|
||||||
|
|
||||||
width_arg = argv[1];
|
codec_arg = argv[1];
|
||||||
height_arg = argv[2];
|
width_arg = argv[2];
|
||||||
infile_arg = argv[3];
|
height_arg = argv[3];
|
||||||
outfile_arg = argv[4];
|
infile_arg = argv[4];
|
||||||
update_frame_num_arg = argv[5];
|
outfile_arg = argv[5];
|
||||||
|
|
||||||
encoder = get_vpx_encoder_by_name("vp9");
|
encoder = get_vpx_encoder_by_name(codec_arg);
|
||||||
if (!encoder) die("Unsupported codec.");
|
if (!encoder)
|
||||||
|
die("Unsupported codec.");
|
||||||
|
|
||||||
update_frame_num = (unsigned int)strtoul(update_frame_num_arg, NULL, 0);
|
update_frame_num = atoi(argv[6]);
|
||||||
// In VP9, the reference buffers (cm->buffer_pool->frame_bufs[i].buf) are
|
// In VP10, the reference buffers (cm->buffer_pool->frame_bufs[i].buf) are
|
||||||
// allocated while calling vpx_codec_encode(), thus, setting reference for
|
// allocated while calling vpx_codec_encode(), thus, setting reference for
|
||||||
// 1st frame isn't supported.
|
// 1st frame isn't supported.
|
||||||
if (update_frame_num <= 1) {
|
if (update_frame_num <= 1)
|
||||||
die("Couldn't parse frame number '%s'\n", update_frame_num_arg);
|
die("Couldn't parse frame number '%s'\n", argv[6]);
|
||||||
}
|
|
||||||
|
|
||||||
if (argc > 6) {
|
if (argc > 7) {
|
||||||
limit = (unsigned int)strtoul(argv[6], NULL, 0);
|
limit = atoi(argv[7]);
|
||||||
if (update_frame_num > limit)
|
if (update_frame_num > limit)
|
||||||
die("Update frame number couldn't larger than limit\n");
|
die("Update frame number couldn't larger than limit\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
info.codec_fourcc = encoder->fourcc;
|
info.codec_fourcc = encoder->fourcc;
|
||||||
info.frame_width = (int)strtol(width_arg, NULL, 0);
|
info.frame_width = strtol(width_arg, NULL, 0);
|
||||||
info.frame_height = (int)strtol(height_arg, NULL, 0);
|
info.frame_height = strtol(height_arg, NULL, 0);
|
||||||
info.time_base.numerator = 1;
|
info.time_base.numerator = 1;
|
||||||
info.time_base.denominator = fps;
|
info.time_base.denominator = fps;
|
||||||
|
|
||||||
if (info.frame_width <= 0 || info.frame_height <= 0 ||
|
if (info.frame_width <= 0 ||
|
||||||
(info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
|
info.frame_height <= 0 ||
|
||||||
|
(info.frame_width % 2) != 0 ||
|
||||||
|
(info.frame_height % 2) != 0) {
|
||||||
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,7 +367,8 @@ int main(int argc, char **argv) {
|
|||||||
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
||||||
|
|
||||||
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
||||||
if (res) die_codec(&ecodec, "Failed to get default codec config.");
|
if (res)
|
||||||
|
die_codec(&ecodec, "Failed to get default codec config.");
|
||||||
|
|
||||||
cfg.g_w = info.frame_width;
|
cfg.g_w = info.frame_width;
|
||||||
cfg.g_h = info.frame_height;
|
cfg.g_h = info.frame_height;
|
||||||
@@ -367,7 +378,8 @@ int main(int argc, char **argv) {
|
|||||||
cfg.g_lag_in_frames = 3;
|
cfg.g_lag_in_frames = 3;
|
||||||
|
|
||||||
writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info);
|
writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info);
|
||||||
if (!writer) die("Failed to open %s for writing.", outfile_arg);
|
if (!writer)
|
||||||
|
die("Failed to open %s for writing.", outfile_arg);
|
||||||
|
|
||||||
if (!(infile = fopen(infile_arg, "rb")))
|
if (!(infile = fopen(infile_arg, "rb")))
|
||||||
die("Failed to open %s for reading.", infile_arg);
|
die("Failed to open %s for reading.", infile_arg);
|
||||||
@@ -380,14 +392,15 @@ int main(int argc, char **argv) {
|
|||||||
die_codec(&ecodec, "Failed to set enable auto alt ref");
|
die_codec(&ecodec, "Failed to set enable auto alt ref");
|
||||||
|
|
||||||
if (test_decode) {
|
if (test_decode) {
|
||||||
const VpxInterface *decoder = get_vpx_decoder_by_name("vp9");
|
const VpxInterface *decoder = get_vpx_decoder_by_name(codec_arg);
|
||||||
if (vpx_codec_dec_init(&dcodec, decoder->codec_interface(), NULL, 0))
|
if (vpx_codec_dec_init(&dcodec, decoder->codec_interface(), NULL, 0))
|
||||||
die_codec(&dcodec, "Failed to initialize decoder.");
|
die_codec(&dcodec, "Failed to initialize decoder.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode frames.
|
// Encode frames.
|
||||||
while (vpx_img_read(&raw, infile)) {
|
while (vpx_img_read(&raw, infile)) {
|
||||||
if (limit && frame_in >= limit) break;
|
if (limit && frame_in >= limit)
|
||||||
|
break;
|
||||||
if (update_frame_num > 1 && frame_out + 1 == update_frame_num) {
|
if (update_frame_num > 1 && frame_out + 1 == update_frame_num) {
|
||||||
vpx_ref_frame_t ref;
|
vpx_ref_frame_t ref;
|
||||||
ref.frame_type = VP8_LAST_FRAME;
|
ref.frame_type = VP8_LAST_FRAME;
|
||||||
@@ -405,17 +418,17 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
encode_frame(&ecodec, &raw, frame_in, writer, test_decode, &dcodec,
|
encode_frame(&ecodec, &cfg, &raw, frame_in, writer, test_decode,
|
||||||
&frame_out, &mismatch_seen);
|
&dcodec, &frame_out, &mismatch_seen);
|
||||||
frame_in++;
|
frame_in++;
|
||||||
if (mismatch_seen) break;
|
if (mismatch_seen)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush encoder.
|
// Flush encoder.
|
||||||
if (!mismatch_seen)
|
if (!mismatch_seen)
|
||||||
while (encode_frame(&ecodec, NULL, frame_in, writer, test_decode, &dcodec,
|
while (encode_frame(&ecodec, &cfg, NULL, frame_in, writer, test_decode,
|
||||||
&frame_out, &mismatch_seen)) {
|
&dcodec, &frame_out, &mismatch_seen)) {}
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
fclose(infile);
|
fclose(infile);
|
||||||
10
ivfdec.c
10
ivfdec.c
@@ -46,8 +46,7 @@ int file_is_ivf(struct VpxInputContext *input_ctx) {
|
|||||||
is_ivf = 1;
|
is_ivf = 1;
|
||||||
|
|
||||||
if (mem_get_le16(raw_hdr + 4) != 0) {
|
if (mem_get_le16(raw_hdr + 4) != 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr, "Error: Unrecognized IVF version! This file may not"
|
||||||
"Error: Unrecognized IVF version! This file may not"
|
|
||||||
" decode properly.");
|
" decode properly.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,13 +69,14 @@ int file_is_ivf(struct VpxInputContext *input_ctx) {
|
|||||||
return is_ivf;
|
return is_ivf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ivf_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read,
|
int ivf_read_frame(FILE *infile, uint8_t **buffer,
|
||||||
size_t *buffer_size) {
|
size_t *bytes_read, size_t *buffer_size) {
|
||||||
char raw_header[IVF_FRAME_HDR_SZ] = {0};
|
char raw_header[IVF_FRAME_HDR_SZ] = {0};
|
||||||
size_t frame_size = 0;
|
size_t frame_size = 0;
|
||||||
|
|
||||||
if (fread(raw_header, IVF_FRAME_HDR_SZ, 1, infile) != 1) {
|
if (fread(raw_header, IVF_FRAME_HDR_SZ, 1, infile) != 1) {
|
||||||
if (!feof(infile)) warn("Failed to read frame size\n");
|
if (!feof(infile))
|
||||||
|
warn("Failed to read frame size\n");
|
||||||
} else {
|
} else {
|
||||||
frame_size = mem_get_le32(raw_header);
|
frame_size = mem_get_le32(raw_header);
|
||||||
|
|
||||||
|
|||||||
4
ivfdec.h
4
ivfdec.h
@@ -18,8 +18,8 @@ extern "C" {
|
|||||||
|
|
||||||
int file_is_ivf(struct VpxInputContext *input);
|
int file_is_ivf(struct VpxInputContext *input);
|
||||||
|
|
||||||
int ivf_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read,
|
int ivf_read_frame(FILE *infile, uint8_t **buffer,
|
||||||
size_t *buffer_size);
|
size_t *bytes_read, size_t *buffer_size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
6
ivfenc.c
6
ivfenc.c
@@ -13,8 +13,10 @@
|
|||||||
#include "vpx/vpx_encoder.h"
|
#include "vpx/vpx_encoder.h"
|
||||||
#include "vpx_ports/mem_ops.h"
|
#include "vpx_ports/mem_ops.h"
|
||||||
|
|
||||||
void ivf_write_file_header(FILE *outfile, const struct vpx_codec_enc_cfg *cfg,
|
void ivf_write_file_header(FILE *outfile,
|
||||||
unsigned int fourcc, int frame_cnt) {
|
const struct vpx_codec_enc_cfg *cfg,
|
||||||
|
unsigned int fourcc,
|
||||||
|
int frame_cnt) {
|
||||||
char header[32];
|
char header[32];
|
||||||
|
|
||||||
header[0] = 'D';
|
header[0] = 'D';
|
||||||
|
|||||||
6
ivfenc.h
6
ivfenc.h
@@ -19,8 +19,10 @@ struct vpx_codec_cx_pkt;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ivf_write_file_header(FILE *outfile, const struct vpx_codec_enc_cfg *cfg,
|
void ivf_write_file_header(FILE *outfile,
|
||||||
uint32_t fourcc, int frame_cnt);
|
const struct vpx_codec_enc_cfg *cfg,
|
||||||
|
uint32_t fourcc,
|
||||||
|
int frame_cnt);
|
||||||
|
|
||||||
void ivf_write_frame_header(FILE *outfile, int64_t pts, size_t frame_size);
|
void ivf_write_frame_header(FILE *outfile, int64_t pts, size_t frame_size);
|
||||||
|
|
||||||
|
|||||||
104
libs.mk
104
libs.mk
@@ -12,7 +12,7 @@
|
|||||||
# ARM assembly files are written in RVCT-style. We use some make magic to
|
# ARM assembly files are written in RVCT-style. We use some make magic to
|
||||||
# filter those files to allow GCC compilation
|
# filter those files to allow GCC compilation
|
||||||
ifeq ($(ARCH_ARM),yes)
|
ifeq ($(ARCH_ARM),yes)
|
||||||
ASM:=$(if $(filter yes,$(CONFIG_GCC)$(CONFIG_MSVS)),.asm.S,.asm)
|
ASM:=$(if $(filter yes,$(CONFIG_GCC)$(CONFIG_MSVS)),.asm.s,.asm)
|
||||||
else
|
else
|
||||||
ASM:=.asm
|
ASM:=.asm
|
||||||
endif
|
endif
|
||||||
@@ -53,59 +53,40 @@ CODEC_SRCS-yes += $(addprefix vpx_dsp/,$(call enabled,DSP_SRCS))
|
|||||||
include $(SRC_PATH_BARE)/vpx_util/vpx_util.mk
|
include $(SRC_PATH_BARE)/vpx_util/vpx_util.mk
|
||||||
CODEC_SRCS-yes += $(addprefix vpx_util/,$(call enabled,UTIL_SRCS))
|
CODEC_SRCS-yes += $(addprefix vpx_util/,$(call enabled,UTIL_SRCS))
|
||||||
|
|
||||||
ifeq ($(CONFIG_VP8),yes)
|
# VP10 make file
|
||||||
VP8_PREFIX=vp8/
|
ifeq ($(CONFIG_VP10),yes)
|
||||||
include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8_common.mk
|
VP10_PREFIX=vp10/
|
||||||
|
include $(SRC_PATH_BARE)/$(VP10_PREFIX)vp10_common.mk
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_VP8_ENCODER),yes)
|
ifeq ($(CONFIG_VP10_ENCODER),yes)
|
||||||
include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8cx.mk
|
VP10_PREFIX=vp10/
|
||||||
CODEC_SRCS-yes += $(addprefix $(VP8_PREFIX),$(call enabled,VP8_CX_SRCS))
|
include $(SRC_PATH_BARE)/$(VP10_PREFIX)vp10cx.mk
|
||||||
CODEC_EXPORTS-yes += $(addprefix $(VP8_PREFIX),$(VP8_CX_EXPORTS))
|
CODEC_SRCS-yes += $(addprefix $(VP10_PREFIX),$(call enabled,VP10_CX_SRCS))
|
||||||
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8cx.h
|
CODEC_EXPORTS-yes += $(addprefix $(VP10_PREFIX),$(VP10_CX_EXPORTS))
|
||||||
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP8_PREFIX)/%
|
CODEC_SRCS-yes += $(VP10_PREFIX)vp10cx.mk vpx/vp8.h vpx/vp8cx.h
|
||||||
CODEC_DOC_SECTIONS += vp8 vp8_encoder
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_VP8_DECODER),yes)
|
|
||||||
include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8dx.mk
|
|
||||||
CODEC_SRCS-yes += $(addprefix $(VP8_PREFIX),$(call enabled,VP8_DX_SRCS))
|
|
||||||
CODEC_EXPORTS-yes += $(addprefix $(VP8_PREFIX),$(VP8_DX_EXPORTS))
|
|
||||||
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8dx.h
|
|
||||||
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP8_PREFIX)/%
|
|
||||||
CODEC_DOC_SECTIONS += vp8 vp8_decoder
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_VP9),yes)
|
|
||||||
VP9_PREFIX=vp9/
|
|
||||||
include $(SRC_PATH_BARE)/$(VP9_PREFIX)vp9_common.mk
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_VP9_ENCODER),yes)
|
|
||||||
VP9_PREFIX=vp9/
|
|
||||||
include $(SRC_PATH_BARE)/$(VP9_PREFIX)vp9cx.mk
|
|
||||||
CODEC_SRCS-yes += $(addprefix $(VP9_PREFIX),$(call enabled,VP9_CX_SRCS))
|
|
||||||
CODEC_EXPORTS-yes += $(addprefix $(VP9_PREFIX),$(VP9_CX_EXPORTS))
|
|
||||||
CODEC_SRCS-yes += $(VP9_PREFIX)vp9cx.mk vpx/vp8.h vpx/vp8cx.h
|
|
||||||
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8cx.h
|
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8cx.h
|
||||||
INSTALL-LIBS-$(CONFIG_SPATIAL_SVC) += include/vpx/svc_context.h
|
INSTALL-LIBS-$(CONFIG_SPATIAL_SVC) += include/vpx/svc_context.h
|
||||||
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP9_PREFIX)/%
|
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP10_PREFIX)/%
|
||||||
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8cx.h
|
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8cx.h
|
||||||
CODEC_DOC_SECTIONS += vp9 vp9_encoder
|
CODEC_DOC_SECTIONS += vp9 vp9_encoder
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_VP9_DECODER),yes)
|
ifeq ($(CONFIG_VP10_DECODER),yes)
|
||||||
VP9_PREFIX=vp9/
|
VP10_PREFIX=vp10/
|
||||||
include $(SRC_PATH_BARE)/$(VP9_PREFIX)vp9dx.mk
|
include $(SRC_PATH_BARE)/$(VP10_PREFIX)vp10dx.mk
|
||||||
CODEC_SRCS-yes += $(addprefix $(VP9_PREFIX),$(call enabled,VP9_DX_SRCS))
|
CODEC_SRCS-yes += $(addprefix $(VP10_PREFIX),$(call enabled,VP10_DX_SRCS))
|
||||||
CODEC_EXPORTS-yes += $(addprefix $(VP9_PREFIX),$(VP9_DX_EXPORTS))
|
CODEC_EXPORTS-yes += $(addprefix $(VP10_PREFIX),$(VP10_DX_EXPORTS))
|
||||||
CODEC_SRCS-yes += $(VP9_PREFIX)vp9dx.mk vpx/vp8.h vpx/vp8dx.h
|
CODEC_SRCS-yes += $(VP10_PREFIX)vp10dx.mk vpx/vp8.h vpx/vp8dx.h
|
||||||
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8dx.h
|
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8dx.h
|
||||||
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP9_PREFIX)/%
|
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP10_PREFIX)/%
|
||||||
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8dx.h
|
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8dx.h
|
||||||
CODEC_DOC_SECTIONS += vp9 vp9_decoder
|
CODEC_DOC_SECTIONS += vp9 vp9_decoder
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
VP10_PREFIX=vp10/
|
||||||
|
$(BUILD_PFX)$(VP10_PREFIX)%.c.o: CFLAGS += -Wextra
|
||||||
|
|
||||||
ifeq ($(CONFIG_ENCODERS),yes)
|
ifeq ($(CONFIG_ENCODERS),yes)
|
||||||
CODEC_DOC_SECTIONS += encoder
|
CODEC_DOC_SECTIONS += encoder
|
||||||
endif
|
endif
|
||||||
@@ -113,12 +94,6 @@ ifeq ($(CONFIG_DECODERS),yes)
|
|||||||
CODEC_DOC_SECTIONS += decoder
|
CODEC_DOC_SECTIONS += decoder
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Suppress -Wextra warnings in third party code.
|
|
||||||
$(BUILD_PFX)third_party/googletest/%.cc.o: CXXFLAGS += -Wno-missing-field-initializers
|
|
||||||
# Suppress -Wextra warnings in first party code pending investigation.
|
|
||||||
# https://bugs.chromium.org/p/webm/issues/detail?id=1069
|
|
||||||
$(BUILD_PFX)vp8/encoder/onyx_if.c.o: CFLAGS += -Wno-unknown-warning-option -Wno-clobbered
|
|
||||||
$(BUILD_PFX)vp8/decoder/onyxd_if.c.o: CFLAGS += -Wno-unknown-warning-option -Wno-clobbered
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_MSVS),yes)
|
ifeq ($(CONFIG_MSVS),yes)
|
||||||
CODEC_LIB=$(if $(CONFIG_STATIC_MSVCRT),vpxmt,vpxmd)
|
CODEC_LIB=$(if $(CONFIG_STATIC_MSVCRT),vpxmt,vpxmd)
|
||||||
@@ -149,7 +124,6 @@ CODEC_SRCS-yes += $(BUILD_PFX)vpx_config.c
|
|||||||
INSTALL-SRCS-no += $(BUILD_PFX)vpx_config.c
|
INSTALL-SRCS-no += $(BUILD_PFX)vpx_config.c
|
||||||
ifeq ($(ARCH_X86)$(ARCH_X86_64),yes)
|
ifeq ($(ARCH_X86)$(ARCH_X86_64),yes)
|
||||||
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += third_party/x86inc/x86inc.asm
|
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += third_party/x86inc/x86inc.asm
|
||||||
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += vpx_dsp/x86/bitdepth_conversion_sse2.asm
|
|
||||||
endif
|
endif
|
||||||
CODEC_EXPORTS-yes += vpx/exports_com
|
CODEC_EXPORTS-yes += vpx/exports_com
|
||||||
CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_enc
|
CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_enc
|
||||||
@@ -188,13 +162,6 @@ libvpx_srcs.txt:
|
|||||||
@echo $(CODEC_SRCS) | xargs -n1 echo | LC_ALL=C sort -u > $@
|
@echo $(CODEC_SRCS) | xargs -n1 echo | LC_ALL=C sort -u > $@
|
||||||
CLEAN-OBJS += libvpx_srcs.txt
|
CLEAN-OBJS += libvpx_srcs.txt
|
||||||
|
|
||||||
# Assembly files that are included, but don't define symbols themselves.
|
|
||||||
# Filtered out to avoid Windows build warnings.
|
|
||||||
ASM_INCLUDES := \
|
|
||||||
third_party/x86inc/x86inc.asm \
|
|
||||||
vpx_config.asm \
|
|
||||||
vpx_ports/x86_abi_support.asm \
|
|
||||||
vpx_dsp/x86/bitdepth_conversion_sse2.asm \
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
|
ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
|
||||||
ifeq ($(CONFIG_MSVS),yes)
|
ifeq ($(CONFIG_MSVS),yes)
|
||||||
@@ -206,6 +173,13 @@ vpx.def: $(call enabled,CODEC_EXPORTS)
|
|||||||
--out=$@ $^
|
--out=$@ $^
|
||||||
CLEAN-OBJS += vpx.def
|
CLEAN-OBJS += vpx.def
|
||||||
|
|
||||||
|
# Assembly files that are included, but don't define symbols themselves.
|
||||||
|
# Filtered out to avoid Visual Studio build warnings.
|
||||||
|
ASM_INCLUDES := \
|
||||||
|
third_party/x86inc/x86inc.asm \
|
||||||
|
vpx_config.asm \
|
||||||
|
vpx_ports/x86_abi_support.asm \
|
||||||
|
|
||||||
vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def
|
vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def
|
||||||
@echo " [CREATE] $@"
|
@echo " [CREATE] $@"
|
||||||
$(qexec)$(GEN_VCPROJ) \
|
$(qexec)$(GEN_VCPROJ) \
|
||||||
@@ -228,12 +202,12 @@ vpx.$(VCPROJ_SFX): $(RTCD)
|
|||||||
|
|
||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
LIBVPX_OBJS=$(call objs, $(filter-out $(ASM_INCLUDES), $(CODEC_SRCS)))
|
LIBVPX_OBJS=$(call objs,$(CODEC_SRCS))
|
||||||
OBJS-yes += $(LIBVPX_OBJS)
|
OBJS-yes += $(LIBVPX_OBJS)
|
||||||
LIBS-$(if yes,$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a
|
LIBS-$(if yes,$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a
|
||||||
$(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS)
|
$(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS)
|
||||||
|
|
||||||
SO_VERSION_MAJOR := 5
|
SO_VERSION_MAJOR := 3
|
||||||
SO_VERSION_MINOR := 0
|
SO_VERSION_MINOR := 0
|
||||||
SO_VERSION_PATCH := 0
|
SO_VERSION_PATCH := 0
|
||||||
ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS))
|
ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS))
|
||||||
@@ -367,7 +341,7 @@ endif
|
|||||||
#
|
#
|
||||||
# Add assembler dependencies for configuration.
|
# Add assembler dependencies for configuration.
|
||||||
#
|
#
|
||||||
$(filter %.S.o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
|
$(filter %.s.o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
|
||||||
$(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
|
$(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
|
||||||
|
|
||||||
|
|
||||||
@@ -392,7 +366,7 @@ LIBVPX_TEST_SRCS=$(addprefix test/,$(call enabled,LIBVPX_TEST_SRCS))
|
|||||||
LIBVPX_TEST_BIN=./test_libvpx$(EXE_SFX)
|
LIBVPX_TEST_BIN=./test_libvpx$(EXE_SFX)
|
||||||
LIBVPX_TEST_DATA=$(addprefix $(LIBVPX_TEST_DATA_PATH)/,\
|
LIBVPX_TEST_DATA=$(addprefix $(LIBVPX_TEST_DATA_PATH)/,\
|
||||||
$(call enabled,LIBVPX_TEST_DATA))
|
$(call enabled,LIBVPX_TEST_DATA))
|
||||||
libvpx_test_data_url=https://storage.googleapis.com/downloads.webmproject.org/test_data/libvpx/$(1)
|
libvpx_test_data_url=http://downloads.webmproject.org/test_data/libvpx/$(1)
|
||||||
|
|
||||||
TEST_INTRA_PRED_SPEED_BIN=./test_intra_pred_speed$(EXE_SFX)
|
TEST_INTRA_PRED_SPEED_BIN=./test_intra_pred_speed$(EXE_SFX)
|
||||||
TEST_INTRA_PRED_SPEED_SRCS=$(addprefix test/,$(call enabled,TEST_INTRA_PRED_SPEED_SRCS))
|
TEST_INTRA_PRED_SPEED_SRCS=$(addprefix test/,$(call enabled,TEST_INTRA_PRED_SPEED_SRCS))
|
||||||
@@ -405,16 +379,8 @@ CLEAN-OBJS += libvpx_test_srcs.txt
|
|||||||
|
|
||||||
$(LIBVPX_TEST_DATA): $(SRC_PATH_BARE)/test/test-data.sha1
|
$(LIBVPX_TEST_DATA): $(SRC_PATH_BARE)/test/test-data.sha1
|
||||||
@echo " [DOWNLOAD] $@"
|
@echo " [DOWNLOAD] $@"
|
||||||
# Attempt to download the file using curl, retrying once if it fails for a
|
$(qexec)trap 'rm -f $@' INT TERM &&\
|
||||||
# partial file (18).
|
curl -L -o $@ $(call libvpx_test_data_url,$(@F))
|
||||||
$(qexec)( \
|
|
||||||
trap 'rm -f $@' INT TERM; \
|
|
||||||
curl="curl --retry 1 -L -o $@ $(call libvpx_test_data_url,$(@F))"; \
|
|
||||||
$$curl; \
|
|
||||||
case "$$?" in \
|
|
||||||
18) $$curl -C -;; \
|
|
||||||
esac \
|
|
||||||
)
|
|
||||||
|
|
||||||
testdata:: $(LIBVPX_TEST_DATA)
|
testdata:: $(LIBVPX_TEST_DATA)
|
||||||
$(qexec)[ -x "$$(which sha1sum)" ] && sha1sum=sha1sum;\
|
$(qexec)[ -x "$$(which sha1sum)" ] && sha1sum=sha1sum;\
|
||||||
|
|||||||
19
md5_utils.c
19
md5_utils.c
@@ -24,13 +24,15 @@
|
|||||||
|
|
||||||
#include "md5_utils.h"
|
#include "md5_utils.h"
|
||||||
|
|
||||||
static void byteSwap(UWORD32 *buf, unsigned words) {
|
static void
|
||||||
|
byteSwap(UWORD32 *buf, unsigned words) {
|
||||||
md5byte *p;
|
md5byte *p;
|
||||||
|
|
||||||
/* Only swap bytes for big endian machines */
|
/* Only swap bytes for big endian machines */
|
||||||
int i = 1;
|
int i = 1;
|
||||||
|
|
||||||
if (*(char *)&i == 1) return;
|
if (*(char *)&i == 1)
|
||||||
|
return;
|
||||||
|
|
||||||
p = (md5byte *)buf;
|
p = (md5byte *)buf;
|
||||||
|
|
||||||
@@ -45,7 +47,8 @@ static void byteSwap(UWORD32 *buf, unsigned words) {
|
|||||||
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||||
* initialization constants.
|
* initialization constants.
|
||||||
*/
|
*/
|
||||||
void MD5Init(struct MD5Context *ctx) {
|
void
|
||||||
|
MD5Init(struct MD5Context *ctx) {
|
||||||
ctx->buf[0] = 0x67452301;
|
ctx->buf[0] = 0x67452301;
|
||||||
ctx->buf[1] = 0xefcdab89;
|
ctx->buf[1] = 0xefcdab89;
|
||||||
ctx->buf[2] = 0x98badcfe;
|
ctx->buf[2] = 0x98badcfe;
|
||||||
@@ -59,7 +62,8 @@ void MD5Init(struct MD5Context *ctx) {
|
|||||||
* Update context to reflect the concatenation of another buffer full
|
* Update context to reflect the concatenation of another buffer full
|
||||||
* of bytes.
|
* of bytes.
|
||||||
*/
|
*/
|
||||||
void MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len) {
|
void
|
||||||
|
MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len) {
|
||||||
UWORD32 t;
|
UWORD32 t;
|
||||||
|
|
||||||
/* Update byte count */
|
/* Update byte count */
|
||||||
@@ -100,7 +104,8 @@ void MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len) {
|
|||||||
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||||
* 1 0* (64-bit count of bits processed, MSB-first)
|
* 1 0* (64-bit count of bits processed, MSB-first)
|
||||||
*/
|
*/
|
||||||
void MD5Final(md5byte digest[16], struct MD5Context *ctx) {
|
void
|
||||||
|
MD5Final(md5byte digest[16], struct MD5Context *ctx) {
|
||||||
int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
|
int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
|
||||||
md5byte *p = (md5byte *)ctx->in + count;
|
md5byte *p = (md5byte *)ctx->in + count;
|
||||||
|
|
||||||
@@ -161,8 +166,8 @@ void MD5Final(md5byte digest[16], struct MD5Context *ctx) {
|
|||||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||||
* the data and converts bytes into longwords for this routine.
|
* the data and converts bytes into longwords for this routine.
|
||||||
*/
|
*/
|
||||||
VPX_NO_UNSIGNED_OVERFLOW_CHECK void MD5Transform(UWORD32 buf[4],
|
VPX_NO_UNSIGNED_OVERFLOW_CHECK void
|
||||||
UWORD32 const in[16]) {
|
MD5Transform(UWORD32 buf[4], UWORD32 const in[16]) {
|
||||||
register UWORD32 a, b, c, d;
|
register UWORD32 a, b, c, d;
|
||||||
|
|
||||||
a = buf[0];
|
a = buf[0];
|
||||||
|
|||||||
82
rate_hist.c
82
rate_hist.c
@@ -37,13 +37,7 @@ struct rate_hist {
|
|||||||
struct rate_hist *init_rate_histogram(const vpx_codec_enc_cfg_t *cfg,
|
struct rate_hist *init_rate_histogram(const vpx_codec_enc_cfg_t *cfg,
|
||||||
const vpx_rational_t *fps) {
|
const vpx_rational_t *fps) {
|
||||||
int i;
|
int i;
|
||||||
struct rate_hist *hist = calloc(1, sizeof(*hist));
|
struct rate_hist *hist = malloc(sizeof(*hist));
|
||||||
|
|
||||||
if (hist == NULL || cfg == NULL || fps == NULL || fps->num == 0 ||
|
|
||||||
fps->den == 0) {
|
|
||||||
destroy_rate_histogram(hist);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the number of samples in the buffer. Use the file's framerate
|
// Determine the number of samples in the buffer. Use the file's framerate
|
||||||
// to determine the number of frames in rc_buf_sz milliseconds, with an
|
// to determine the number of frames in rc_buf_sz milliseconds, with an
|
||||||
@@ -51,7 +45,8 @@ struct rate_hist *init_rate_histogram(const vpx_codec_enc_cfg_t *cfg,
|
|||||||
hist->samples = cfg->rc_buf_sz * 5 / 4 * fps->num / fps->den / 1000;
|
hist->samples = cfg->rc_buf_sz * 5 / 4 * fps->num / fps->den / 1000;
|
||||||
|
|
||||||
// prevent division by zero
|
// prevent division by zero
|
||||||
if (hist->samples == 0) hist->samples = 1;
|
if (hist->samples == 0)
|
||||||
|
hist->samples = 1;
|
||||||
|
|
||||||
hist->frames = 0;
|
hist->frames = 0;
|
||||||
hist->total = 0;
|
hist->total = 0;
|
||||||
@@ -86,17 +81,15 @@ void update_rate_histogram(struct rate_hist *hist,
|
|||||||
(uint64_t)cfg->g_timebase.num /
|
(uint64_t)cfg->g_timebase.num /
|
||||||
(uint64_t)cfg->g_timebase.den;
|
(uint64_t)cfg->g_timebase.den;
|
||||||
|
|
||||||
int idx;
|
int idx = hist->frames++ % hist->samples;
|
||||||
|
|
||||||
if (hist == NULL || cfg == NULL || pkt == NULL) return;
|
|
||||||
|
|
||||||
idx = hist->frames++ % hist->samples;
|
|
||||||
hist->pts[idx] = now;
|
hist->pts[idx] = now;
|
||||||
hist->sz[idx] = (int)pkt->data.frame.sz;
|
hist->sz[idx] = (int)pkt->data.frame.sz;
|
||||||
|
|
||||||
if (now < cfg->rc_buf_initial_sz) return;
|
if (now < cfg->rc_buf_initial_sz)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!cfg->rc_target_bitrate) return;
|
if (!cfg->rc_target_bitrate)
|
||||||
|
return;
|
||||||
|
|
||||||
then = now;
|
then = now;
|
||||||
|
|
||||||
@@ -105,16 +98,20 @@ void update_rate_histogram(struct rate_hist *hist,
|
|||||||
const int i_idx = (i - 1) % hist->samples;
|
const int i_idx = (i - 1) % hist->samples;
|
||||||
|
|
||||||
then = hist->pts[i_idx];
|
then = hist->pts[i_idx];
|
||||||
if (now - then > cfg->rc_buf_sz) break;
|
if (now - then > cfg->rc_buf_sz)
|
||||||
|
break;
|
||||||
sum_sz += hist->sz[i_idx];
|
sum_sz += hist->sz[i_idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (now == then) return;
|
if (now == then)
|
||||||
|
return;
|
||||||
|
|
||||||
avg_bitrate = sum_sz * 8 * 1000 / (now - then);
|
avg_bitrate = sum_sz * 8 * 1000 / (now - then);
|
||||||
idx = (int)(avg_bitrate * (RATE_BINS / 2) / (cfg->rc_target_bitrate * 1000));
|
idx = (int)(avg_bitrate * (RATE_BINS / 2) / (cfg->rc_target_bitrate * 1000));
|
||||||
if (idx < 0) idx = 0;
|
if (idx < 0)
|
||||||
if (idx > RATE_BINS - 1) idx = RATE_BINS - 1;
|
idx = 0;
|
||||||
|
if (idx > RATE_BINS - 1)
|
||||||
|
idx = RATE_BINS - 1;
|
||||||
if (hist->bucket[idx].low > avg_bitrate)
|
if (hist->bucket[idx].low > avg_bitrate)
|
||||||
hist->bucket[idx].low = (int)avg_bitrate;
|
hist->bucket[idx].low = (int)avg_bitrate;
|
||||||
if (hist->bucket[idx].high < avg_bitrate)
|
if (hist->bucket[idx].high < avg_bitrate)
|
||||||
@@ -123,22 +120,19 @@ void update_rate_histogram(struct rate_hist *hist,
|
|||||||
hist->total++;
|
hist->total++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int merge_hist_buckets(struct hist_bucket *bucket, int max_buckets,
|
static int merge_hist_buckets(struct hist_bucket *bucket,
|
||||||
int *num_buckets) {
|
int max_buckets, int *num_buckets) {
|
||||||
int small_bucket = 0, merge_bucket = INT_MAX, big_bucket = 0;
|
int small_bucket = 0, merge_bucket = INT_MAX, big_bucket = 0;
|
||||||
int buckets;
|
int buckets = *num_buckets;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
assert(bucket != NULL);
|
|
||||||
assert(num_buckets != NULL);
|
|
||||||
|
|
||||||
buckets = *num_buckets;
|
|
||||||
|
|
||||||
/* Find the extrema for this list of buckets */
|
/* Find the extrema for this list of buckets */
|
||||||
big_bucket = small_bucket = 0;
|
big_bucket = small_bucket = 0;
|
||||||
for (i = 0; i < buckets; i++) {
|
for (i = 0; i < buckets; i++) {
|
||||||
if (bucket[i].count < bucket[small_bucket].count) small_bucket = i;
|
if (bucket[i].count < bucket[small_bucket].count)
|
||||||
if (bucket[i].count > bucket[big_bucket].count) big_bucket = i;
|
small_bucket = i;
|
||||||
|
if (bucket[i].count > bucket[big_bucket].count)
|
||||||
|
big_bucket = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we have too many buckets, merge the smallest with an adjacent
|
/* If we have too many buckets, merge the smallest with an adjacent
|
||||||
@@ -180,10 +174,13 @@ static int merge_hist_buckets(struct hist_bucket *bucket, int max_buckets,
|
|||||||
*/
|
*/
|
||||||
big_bucket = small_bucket = 0;
|
big_bucket = small_bucket = 0;
|
||||||
for (i = 0; i < buckets; i++) {
|
for (i = 0; i < buckets; i++) {
|
||||||
if (i > merge_bucket) bucket[i] = bucket[i + 1];
|
if (i > merge_bucket)
|
||||||
|
bucket[i] = bucket[i + 1];
|
||||||
|
|
||||||
if (bucket[i].count < bucket[small_bucket].count) small_bucket = i;
|
if (bucket[i].count < bucket[small_bucket].count)
|
||||||
if (bucket[i].count > bucket[big_bucket].count) big_bucket = i;
|
small_bucket = i;
|
||||||
|
if (bucket[i].count > bucket[big_bucket].count)
|
||||||
|
big_bucket = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,13 +188,11 @@ static int merge_hist_buckets(struct hist_bucket *bucket, int max_buckets,
|
|||||||
return bucket[big_bucket].count;
|
return bucket[big_bucket].count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_histogram(const struct hist_bucket *bucket, int buckets,
|
static void show_histogram(const struct hist_bucket *bucket,
|
||||||
int total, int scale) {
|
int buckets, int total, int scale) {
|
||||||
const char *pat1, *pat2;
|
const char *pat1, *pat2;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
assert(bucket != NULL);
|
|
||||||
|
|
||||||
switch ((int)(log(bucket[buckets - 1].high) / log(10)) + 1) {
|
switch ((int)(log(bucket[buckets - 1].high) / log(10)) + 1) {
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
@@ -237,7 +232,8 @@ static void show_histogram(const struct hist_bucket *bucket, int buckets,
|
|||||||
|
|
||||||
pct = (float)(100.0 * bucket[i].count / total);
|
pct = (float)(100.0 * bucket[i].count / total);
|
||||||
len = HIST_BAR_MAX * bucket[i].count / scale;
|
len = HIST_BAR_MAX * bucket[i].count / scale;
|
||||||
if (len < 1) len = 1;
|
if (len < 1)
|
||||||
|
len = 1;
|
||||||
assert(len <= HIST_BAR_MAX);
|
assert(len <= HIST_BAR_MAX);
|
||||||
|
|
||||||
if (bucket[i].low == bucket[i].high)
|
if (bucket[i].low == bucket[i].high)
|
||||||
@@ -245,7 +241,8 @@ static void show_histogram(const struct hist_bucket *bucket, int buckets,
|
|||||||
else
|
else
|
||||||
fprintf(stderr, pat2, bucket[i].low, bucket[i].high);
|
fprintf(stderr, pat2, bucket[i].low, bucket[i].high);
|
||||||
|
|
||||||
for (j = 0; j < HIST_BAR_MAX; j++) fprintf(stderr, j < len ? "=" : " ");
|
for (j = 0; j < HIST_BAR_MAX; j++)
|
||||||
|
fprintf(stderr, j < len ? "=" : " ");
|
||||||
fprintf(stderr, "\t%5d (%6.2f%%)\n", bucket[i].count, pct);
|
fprintf(stderr, "\t%5d (%6.2f%%)\n", bucket[i].count, pct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,15 +268,14 @@ void show_q_histogram(const int counts[64], int max_buckets) {
|
|||||||
show_histogram(bucket, buckets, total, scale);
|
show_histogram(bucket, buckets, total, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
void show_rate_histogram(struct rate_hist *hist, const vpx_codec_enc_cfg_t *cfg,
|
void show_rate_histogram(struct rate_hist *hist,
|
||||||
int max_buckets) {
|
const vpx_codec_enc_cfg_t *cfg, int max_buckets) {
|
||||||
int i, scale;
|
int i, scale;
|
||||||
int buckets = 0;
|
int buckets = 0;
|
||||||
|
|
||||||
if (hist == NULL || cfg == NULL) return;
|
|
||||||
|
|
||||||
for (i = 0; i < RATE_BINS; i++) {
|
for (i = 0; i < RATE_BINS; i++) {
|
||||||
if (hist->bucket[i].low == INT_MAX) continue;
|
if (hist->bucket[i].low == INT_MAX)
|
||||||
|
continue;
|
||||||
hist->bucket[buckets++] = hist->bucket[i];
|
hist->bucket[buckets++] = hist->bucket[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,6 @@
|
|||||||
#ifndef TEST_ACM_RANDOM_H_
|
#ifndef TEST_ACM_RANDOM_H_
|
||||||
#define TEST_ACM_RANDOM_H_
|
#define TEST_ACM_RANDOM_H_
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
@@ -27,7 +23,9 @@ class ACMRandom {
|
|||||||
|
|
||||||
explicit ACMRandom(int seed) : random_(seed) {}
|
explicit ACMRandom(int seed) : random_(seed) {}
|
||||||
|
|
||||||
void Reset(int seed) { random_.Reseed(seed); }
|
void Reset(int seed) {
|
||||||
|
random_.Reseed(seed);
|
||||||
|
}
|
||||||
uint16_t Rand16(void) {
|
uint16_t Rand16(void) {
|
||||||
const uint32_t value =
|
const uint32_t value =
|
||||||
random_.Generate(testing::internal::Random::kMaxRange);
|
random_.Generate(testing::internal::Random::kMaxRange);
|
||||||
@@ -54,18 +52,17 @@ class ACMRandom {
|
|||||||
return r < 128 ? r << 4 : r >> 4;
|
return r < 128 ? r << 4 : r >> 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RandRange(const uint32_t range) {
|
int PseudoUniform(int range) {
|
||||||
// testing::internal::Random::Generate provides values in the range
|
|
||||||
// testing::internal::Random::kMaxRange.
|
|
||||||
assert(range <= testing::internal::Random::kMaxRange);
|
|
||||||
return random_.Generate(range);
|
return random_.Generate(range);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PseudoUniform(int range) { return random_.Generate(range); }
|
int operator()(int n) {
|
||||||
|
return PseudoUniform(n);
|
||||||
|
}
|
||||||
|
|
||||||
int operator()(int n) { return PseudoUniform(n); }
|
static int DeterministicSeed(void) {
|
||||||
|
return 0xbaba;
|
||||||
static int DeterministicSeed(void) { return 0xbaba; }
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
testing::internal::Random random_;
|
testing::internal::Random random_;
|
||||||
|
|||||||
@@ -17,8 +17,8 @@
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Check if any pixel in a 16x16 macroblock varies between frames.
|
// Check if any pixel in a 16x16 macroblock varies between frames.
|
||||||
int CheckMb(const vpx_image_t ¤t, const vpx_image_t &previous, int mb_r,
|
int CheckMb(const vpx_image_t ¤t, const vpx_image_t &previous,
|
||||||
int mb_c) {
|
int mb_r, int mb_c) {
|
||||||
for (int plane = 0; plane < 3; plane++) {
|
for (int plane = 0; plane < 3; plane++) {
|
||||||
int r = 16 * mb_r;
|
int r = 16 * mb_r;
|
||||||
int c0 = 16 * mb_c;
|
int c0 = 16 * mb_c;
|
||||||
@@ -37,12 +37,11 @@ int CheckMb(const vpx_image_t ¤t, const vpx_image_t &previous, int mb_r,
|
|||||||
for (; r < r_top; ++r) {
|
for (; r < r_top; ++r) {
|
||||||
for (int c = c0; c < c_top; ++c) {
|
for (int c = c0; c < c_top; ++c) {
|
||||||
if (current.planes[plane][current.stride[plane] * r + c] !=
|
if (current.planes[plane][current.stride[plane] * r + c] !=
|
||||||
previous.planes[plane][previous.stride[plane] * r + c]) {
|
previous.planes[plane][previous.stride[plane] * r + c])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,15 +113,22 @@ TEST_P(ActiveMapRefreshTest, Test) {
|
|||||||
cfg_.rc_end_usage = VPX_CBR;
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
cfg_.kf_max_dist = 90000;
|
cfg_.kf_max_dist = 90000;
|
||||||
|
|
||||||
::libvpx_test::Y4mVideoSource video("desktop_credits.y4m", 0, 30);
|
#if CONFIG_VP10
|
||||||
::libvpx_test::Y4mVideoSource video_holder("desktop_credits.y4m", 0, 30);
|
const int nframes = codec_ == &libvpx_test::kVP10 ? 10 : 30;
|
||||||
|
#else
|
||||||
|
const int nframes = 30;
|
||||||
|
#endif // CONFIG_VP10
|
||||||
|
::libvpx_test::Y4mVideoSource video("desktop_credits.y4m", 0, nframes);
|
||||||
|
::libvpx_test::Y4mVideoSource video_holder("desktop_credits.y4m", 0, nframes);
|
||||||
video_holder.Begin();
|
video_holder.Begin();
|
||||||
y4m_holder_ = &video_holder;
|
y4m_holder_ = &video_holder;
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
}
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(ActiveMapRefreshTest,
|
#if CONFIG_VP10
|
||||||
|
VP10_INSTANTIATE_TEST_CASE(ActiveMapRefreshTest,
|
||||||
::testing::Values(::libvpx_test::kRealTime),
|
::testing::Values(::libvpx_test::kRealTime),
|
||||||
::testing::Range(5, 6));
|
::testing::Range(5, 6));
|
||||||
|
#endif // CONFIG_VP10
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ class ActiveMapTest
|
|||||||
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
||||||
} else if (video->frame() == 3) {
|
} else if (video->frame() == 3) {
|
||||||
vpx_active_map_t map = vpx_active_map_t();
|
vpx_active_map_t map = vpx_active_map_t();
|
||||||
/* clang-format off */
|
|
||||||
uint8_t active_map[9 * 13] = {
|
uint8_t active_map[9 * 13] = {
|
||||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0,
|
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0,
|
||||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0,
|
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0,
|
||||||
@@ -51,7 +50,6 @@ class ActiveMapTest
|
|||||||
0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1,
|
0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1,
|
||||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0,
|
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0,
|
||||||
};
|
};
|
||||||
/* clang-format on */
|
|
||||||
map.cols = (kWidth + 15) / 16;
|
map.cols = (kWidth + 15) / 16;
|
||||||
map.rows = (kHeight + 15) / 16;
|
map.rows = (kHeight + 15) / 16;
|
||||||
ASSERT_EQ(map.cols, 13u);
|
ASSERT_EQ(map.cols, 13u);
|
||||||
@@ -67,10 +65,7 @@ class ActiveMapTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int cpu_used_;
|
void DoTest() {
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(ActiveMapTest, Test) {
|
|
||||||
// Validate that this non multiple of 64 wide clip encodes
|
// Validate that this non multiple of 64 wide clip encodes
|
||||||
cfg_.g_lag_in_frames = 0;
|
cfg_.g_lag_in_frames = 0;
|
||||||
cfg_.rc_target_bitrate = 400;
|
cfg_.rc_target_bitrate = 400;
|
||||||
@@ -78,14 +73,31 @@ TEST_P(ActiveMapTest, Test) {
|
|||||||
cfg_.g_pass = VPX_RC_ONE_PASS;
|
cfg_.g_pass = VPX_RC_ONE_PASS;
|
||||||
cfg_.rc_end_usage = VPX_CBR;
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
cfg_.kf_max_dist = 90000;
|
cfg_.kf_max_dist = 90000;
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_odd.yuv", kWidth, kHeight, 30,
|
||||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", kWidth, kHeight, 30, 1,
|
1, 0, 20);
|
||||||
0, 20);
|
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
}
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(ActiveMapTest,
|
int cpu_used_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(ActiveMapTest, Test) {
|
||||||
|
DoTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ActiveMapTestLarge : public ActiveMapTest {};
|
||||||
|
|
||||||
|
TEST_P(ActiveMapTestLarge, Test) {
|
||||||
|
DoTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
VP10_INSTANTIATE_TEST_CASE(ActiveMapTestLarge,
|
||||||
::testing::Values(::libvpx_test::kRealTime),
|
::testing::Values(::libvpx_test::kRealTime),
|
||||||
::testing::Range(0, 9));
|
::testing::Range(0, 5));
|
||||||
|
|
||||||
|
VP10_INSTANTIATE_TEST_CASE(ActiveMapTest,
|
||||||
|
::testing::Values(::libvpx_test::kRealTime),
|
||||||
|
::testing::Range(5, 9));
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -18,16 +18,18 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static const int kNoiseSize = 3072;
|
|
||||||
|
|
||||||
// TODO(jimbankoski): make width and height integers not unsigned.
|
// TODO(jimbankoski): make width and height integers not unsigned.
|
||||||
typedef void (*AddNoiseFunc)(uint8_t *start, const int8_t *noise,
|
typedef void (*AddNoiseFunc)(unsigned char *start, char *noise,
|
||||||
int blackclamp, int whiteclamp, int width,
|
char blackclamp[16], char whiteclamp[16],
|
||||||
int height, int pitch);
|
char bothclamp[16], unsigned int width,
|
||||||
|
unsigned int height, int pitch);
|
||||||
|
|
||||||
class AddNoiseTest : public ::testing::TestWithParam<AddNoiseFunc> {
|
class AddNoiseTest
|
||||||
|
: public ::testing::TestWithParam<AddNoiseFunc> {
|
||||||
public:
|
public:
|
||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
virtual void TearDown() {
|
||||||
|
libvpx_test::ClearSystemState();
|
||||||
|
}
|
||||||
virtual ~AddNoiseTest() {}
|
virtual ~AddNoiseTest() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -40,18 +42,26 @@ double stddev6(char a, char b, char c, char d, char e, char f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(AddNoiseTest, CheckNoiseAdded) {
|
TEST_P(AddNoiseTest, CheckNoiseAdded) {
|
||||||
|
DECLARE_ALIGNED(16, char, blackclamp[16]);
|
||||||
|
DECLARE_ALIGNED(16, char, whiteclamp[16]);
|
||||||
|
DECLARE_ALIGNED(16, char, bothclamp[16]);
|
||||||
const int width = 64;
|
const int width = 64;
|
||||||
const int height = 64;
|
const int height = 64;
|
||||||
const int image_size = width * height;
|
const int image_size = width * height;
|
||||||
int8_t noise[kNoiseSize];
|
char noise[3072];
|
||||||
const int clamp = vpx_setup_noise(4.4, noise, kNoiseSize);
|
const int clamp = vpx_setup_noise(4.4, sizeof(noise), noise);
|
||||||
uint8_t *const s =
|
|
||||||
reinterpret_cast<uint8_t *>(vpx_calloc(image_size, sizeof(*s)));
|
|
||||||
ASSERT_TRUE(s != NULL);
|
|
||||||
memset(s, 99, image_size * sizeof(*s));
|
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
for (int i = 0; i < 16; i++) {
|
||||||
GetParam()(s, noise, clamp, clamp, width, height, width));
|
blackclamp[i] = clamp;
|
||||||
|
whiteclamp[i] = clamp;
|
||||||
|
bothclamp[i] = 2 * clamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *const s = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
|
||||||
|
memset(s, 99, image_size);
|
||||||
|
|
||||||
|
ASM_REGISTER_STATE_CHECK(GetParam()(s, noise, blackclamp, whiteclamp,
|
||||||
|
bothclamp, width, height, width));
|
||||||
|
|
||||||
// Check to make sure we don't end up having either the same or no added
|
// Check to make sure we don't end up having either the same or no added
|
||||||
// noise either vertically or horizontally.
|
// noise either vertically or horizontally.
|
||||||
@@ -69,8 +79,8 @@ TEST_P(AddNoiseTest, CheckNoiseAdded) {
|
|||||||
// Initialize pixels in the image to 255 and check for roll over.
|
// Initialize pixels in the image to 255 and check for roll over.
|
||||||
memset(s, 255, image_size);
|
memset(s, 255, image_size);
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(GetParam()(s, noise, blackclamp, whiteclamp,
|
||||||
GetParam()(s, noise, clamp, clamp, width, height, width));
|
bothclamp, width, height, width));
|
||||||
|
|
||||||
// Check to make sure don't roll over.
|
// Check to make sure don't roll over.
|
||||||
for (int i = 0; i < image_size; ++i) {
|
for (int i = 0; i < image_size; ++i) {
|
||||||
@@ -80,8 +90,8 @@ TEST_P(AddNoiseTest, CheckNoiseAdded) {
|
|||||||
// Initialize pixels in the image to 0 and check for roll under.
|
// Initialize pixels in the image to 0 and check for roll under.
|
||||||
memset(s, 0, image_size);
|
memset(s, 0, image_size);
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(GetParam()(s, noise, blackclamp, whiteclamp,
|
||||||
GetParam()(s, noise, clamp, clamp, width, height, width));
|
bothclamp, width, height, width));
|
||||||
|
|
||||||
// Check to make sure don't roll under.
|
// Check to make sure don't roll under.
|
||||||
for (int i = 0; i < image_size; ++i) {
|
for (int i = 0; i < image_size; ++i) {
|
||||||
@@ -92,26 +102,35 @@ TEST_P(AddNoiseTest, CheckNoiseAdded) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(AddNoiseTest, CheckCvsAssembly) {
|
TEST_P(AddNoiseTest, CheckCvsAssembly) {
|
||||||
|
DECLARE_ALIGNED(16, char, blackclamp[16]);
|
||||||
|
DECLARE_ALIGNED(16, char, whiteclamp[16]);
|
||||||
|
DECLARE_ALIGNED(16, char, bothclamp[16]);
|
||||||
const int width = 64;
|
const int width = 64;
|
||||||
const int height = 64;
|
const int height = 64;
|
||||||
const int image_size = width * height;
|
const int image_size = width * height;
|
||||||
int8_t noise[kNoiseSize];
|
char noise[3072];
|
||||||
const int clamp = vpx_setup_noise(4.4, noise, kNoiseSize);
|
|
||||||
|
const int clamp = vpx_setup_noise(4.4, sizeof(noise), noise);
|
||||||
|
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
blackclamp[i] = clamp;
|
||||||
|
whiteclamp[i] = clamp;
|
||||||
|
bothclamp[i] = 2 * clamp;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t *const s = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
|
uint8_t *const s = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
|
||||||
uint8_t *const d = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
|
uint8_t *const d = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
|
||||||
ASSERT_TRUE(s != NULL);
|
|
||||||
ASSERT_TRUE(d != NULL);
|
|
||||||
|
|
||||||
memset(s, 99, image_size);
|
memset(s, 99, image_size);
|
||||||
memset(d, 99, image_size);
|
memset(d, 99, image_size);
|
||||||
|
|
||||||
srand(0);
|
srand(0);
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(GetParam()(s, noise, blackclamp, whiteclamp,
|
||||||
GetParam()(s, noise, clamp, clamp, width, height, width));
|
bothclamp, width, height, width));
|
||||||
srand(0);
|
srand(0);
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(vpx_plane_add_noise_c(d, noise, blackclamp,
|
||||||
vpx_plane_add_noise_c(d, noise, clamp, clamp, width, height, width));
|
whiteclamp, bothclamp,
|
||||||
|
width, height, width));
|
||||||
|
|
||||||
for (int i = 0; i < image_size; ++i) {
|
for (int i = 0; i < image_size; ++i) {
|
||||||
EXPECT_EQ(static_cast<int>(s[i]), static_cast<int>(d[i])) << "i = " << i;
|
EXPECT_EQ(static_cast<int>(s[i]), static_cast<int>(d[i])) << "i = " << i;
|
||||||
|
|||||||
@@ -1,157 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
#include "test/codec_factory.h"
|
|
||||||
#include "test/encode_test_driver.h"
|
|
||||||
#include "test/i420_video_source.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
class AltRefAqSegmentTest
|
|
||||||
: public ::libvpx_test::EncoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
|
||||||
protected:
|
|
||||||
AltRefAqSegmentTest() : EncoderTest(GET_PARAM(0)) {}
|
|
||||||
virtual ~AltRefAqSegmentTest() {}
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
|
||||||
InitializeConfig();
|
|
||||||
SetMode(GET_PARAM(1));
|
|
||||||
set_cpu_used_ = GET_PARAM(2);
|
|
||||||
aq_mode_ = 0;
|
|
||||||
alt_ref_aq_mode_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
|
||||||
::libvpx_test::Encoder *encoder) {
|
|
||||||
if (video->frame() == 1) {
|
|
||||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
|
||||||
encoder->Control(VP9E_SET_ALT_REF_AQ, alt_ref_aq_mode_);
|
|
||||||
encoder->Control(VP9E_SET_AQ_MODE, aq_mode_);
|
|
||||||
encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int set_cpu_used_;
|
|
||||||
int aq_mode_;
|
|
||||||
int alt_ref_aq_mode_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Validate that this ALT_REF_AQ/AQ segmentation mode
|
|
||||||
// (ALT_REF_AQ=0, AQ=0/no_aq)
|
|
||||||
// encodes and decodes without a mismatch.
|
|
||||||
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ0) {
|
|
||||||
cfg_.rc_min_quantizer = 8;
|
|
||||||
cfg_.rc_max_quantizer = 56;
|
|
||||||
cfg_.rc_end_usage = VPX_VBR;
|
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
|
||||||
cfg_.rc_buf_sz = 1000;
|
|
||||||
cfg_.rc_target_bitrate = 300;
|
|
||||||
|
|
||||||
aq_mode_ = 0;
|
|
||||||
alt_ref_aq_mode_ = 1;
|
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
|
||||||
30, 1, 0, 100);
|
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate that this ALT_REF_AQ/AQ segmentation mode
|
|
||||||
// (ALT_REF_AQ=0, AQ=1/variance_aq)
|
|
||||||
// encodes and decodes without a mismatch.
|
|
||||||
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ1) {
|
|
||||||
cfg_.rc_min_quantizer = 8;
|
|
||||||
cfg_.rc_max_quantizer = 56;
|
|
||||||
cfg_.rc_end_usage = VPX_VBR;
|
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
|
||||||
cfg_.rc_buf_sz = 1000;
|
|
||||||
cfg_.rc_target_bitrate = 300;
|
|
||||||
|
|
||||||
aq_mode_ = 1;
|
|
||||||
alt_ref_aq_mode_ = 1;
|
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
|
||||||
30, 1, 0, 100);
|
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate that this ALT_REF_AQ/AQ segmentation mode
|
|
||||||
// (ALT_REF_AQ=0, AQ=2/complexity_aq)
|
|
||||||
// encodes and decodes without a mismatch.
|
|
||||||
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ2) {
|
|
||||||
cfg_.rc_min_quantizer = 8;
|
|
||||||
cfg_.rc_max_quantizer = 56;
|
|
||||||
cfg_.rc_end_usage = VPX_VBR;
|
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
|
||||||
cfg_.rc_buf_sz = 1000;
|
|
||||||
cfg_.rc_target_bitrate = 300;
|
|
||||||
|
|
||||||
aq_mode_ = 2;
|
|
||||||
alt_ref_aq_mode_ = 1;
|
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
|
||||||
30, 1, 0, 100);
|
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate that this ALT_REF_AQ/AQ segmentation mode
|
|
||||||
// (ALT_REF_AQ=0, AQ=3/cyclicrefresh_aq)
|
|
||||||
// encodes and decodes without a mismatch.
|
|
||||||
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ3) {
|
|
||||||
cfg_.rc_min_quantizer = 8;
|
|
||||||
cfg_.rc_max_quantizer = 56;
|
|
||||||
cfg_.rc_end_usage = VPX_VBR;
|
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
|
||||||
cfg_.rc_buf_sz = 1000;
|
|
||||||
cfg_.rc_target_bitrate = 300;
|
|
||||||
|
|
||||||
aq_mode_ = 3;
|
|
||||||
alt_ref_aq_mode_ = 1;
|
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
|
||||||
30, 1, 0, 100);
|
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate that this ALT_REF_AQ/AQ segmentation mode
|
|
||||||
// (ALT_REF_AQ=0, AQ=4/equator360_aq)
|
|
||||||
// encodes and decodes without a mismatch.
|
|
||||||
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ4) {
|
|
||||||
cfg_.rc_min_quantizer = 8;
|
|
||||||
cfg_.rc_max_quantizer = 56;
|
|
||||||
cfg_.rc_end_usage = VPX_VBR;
|
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
|
||||||
cfg_.rc_buf_sz = 1000;
|
|
||||||
cfg_.rc_target_bitrate = 300;
|
|
||||||
|
|
||||||
aq_mode_ = 4;
|
|
||||||
alt_ref_aq_mode_ = 1;
|
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
|
||||||
30, 1, 0, 100);
|
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
}
|
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(AltRefAqSegmentTest,
|
|
||||||
::testing::Values(::libvpx_test::kOnePassGood,
|
|
||||||
::libvpx_test::kTwoPassGood),
|
|
||||||
::testing::Range(2, 5));
|
|
||||||
} // namespace
|
|
||||||
@@ -14,67 +14,16 @@
|
|||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
#if CONFIG_VP8_ENCODER
|
|
||||||
|
|
||||||
// lookahead range: [kLookAheadMin, kLookAheadMax).
|
|
||||||
const int kLookAheadMin = 5;
|
|
||||||
const int kLookAheadMax = 26;
|
|
||||||
|
|
||||||
class AltRefTest : public ::libvpx_test::EncoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWithParam<int> {
|
|
||||||
protected:
|
|
||||||
AltRefTest() : EncoderTest(GET_PARAM(0)), altref_count_(0) {}
|
|
||||||
virtual ~AltRefTest() {}
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
|
||||||
InitializeConfig();
|
|
||||||
SetMode(libvpx_test::kTwoPassGood);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void BeginPassHook(unsigned int /*pass*/) { altref_count_ = 0; }
|
|
||||||
|
|
||||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
|
||||||
libvpx_test::Encoder *encoder) {
|
|
||||||
if (video->frame() == 1) {
|
|
||||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
|
||||||
encoder->Control(VP8E_SET_CPUUSED, 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
|
||||||
if (pkt->data.frame.flags & VPX_FRAME_IS_INVISIBLE) ++altref_count_;
|
|
||||||
}
|
|
||||||
|
|
||||||
int altref_count() const { return altref_count_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
int altref_count_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(AltRefTest, MonotonicTimestamps) {
|
|
||||||
const vpx_rational timebase = { 33333333, 1000000000 };
|
|
||||||
cfg_.g_timebase = timebase;
|
|
||||||
cfg_.rc_target_bitrate = 1000;
|
|
||||||
cfg_.g_lag_in_frames = GET_PARAM(1);
|
|
||||||
|
|
||||||
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
|
||||||
timebase.den, timebase.num, 0, 30);
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
EXPECT_GE(altref_count(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
VP8_INSTANTIATE_TEST_CASE(AltRefTest,
|
|
||||||
::testing::Range(kLookAheadMin, kLookAheadMax));
|
|
||||||
|
|
||||||
#endif // CONFIG_VP8_ENCODER
|
|
||||||
|
|
||||||
class AltRefForcedKeyTestLarge
|
class AltRefForcedKeyTestLarge
|
||||||
: public ::libvpx_test::EncoderTest,
|
: public ::libvpx_test::EncoderTest,
|
||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||||
protected:
|
protected:
|
||||||
AltRefForcedKeyTestLarge()
|
AltRefForcedKeyTestLarge()
|
||||||
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
|
: EncoderTest(GET_PARAM(0)),
|
||||||
cpu_used_(GET_PARAM(2)), forced_kf_frame_num_(1), frame_num_(0) {}
|
encoding_mode_(GET_PARAM(1)),
|
||||||
|
cpu_used_(GET_PARAM(2)),
|
||||||
|
forced_kf_frame_num_(1),
|
||||||
|
frame_num_(0) {}
|
||||||
virtual ~AltRefForcedKeyTestLarge() {}
|
virtual ~AltRefForcedKeyTestLarge() {}
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
@@ -89,9 +38,9 @@ class AltRefForcedKeyTestLarge
|
|||||||
if (video->frame() == 0) {
|
if (video->frame() == 0) {
|
||||||
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
||||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||||
#if CONFIG_VP9_ENCODER
|
|
||||||
// override test default for tile columns if necessary.
|
// override test default for tile columns if necessary.
|
||||||
if (GET_PARAM(0) == &libvpx_test::kVP9) {
|
#if CONFIG_VP10_ENCODER
|
||||||
|
if (GET_PARAM(0) == &libvpx_test::kVP10) {
|
||||||
encoder->Control(VP9E_SET_TILE_COLUMNS, 6);
|
encoder->Control(VP9E_SET_TILE_COLUMNS, 6);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -142,11 +91,9 @@ TEST_P(AltRefForcedKeyTestLarge, ForcedFrameIsKey) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VP8_INSTANTIATE_TEST_CASE(AltRefForcedKeyTestLarge,
|
VP10_INSTANTIATE_TEST_CASE(
|
||||||
|
AltRefForcedKeyTestLarge,
|
||||||
::testing::Values(::libvpx_test::kOnePassGood),
|
::testing::Values(::libvpx_test::kOnePassGood),
|
||||||
::testing::Range(0, 9));
|
::testing::Range(0, 9));
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(AltRefForcedKeyTestLarge,
|
|
||||||
::testing::Values(::libvpx_test::kOnePassGood),
|
|
||||||
::testing::Range(0, 9));
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ LOCAL_CPP_EXTENSION := .cc
|
|||||||
LOCAL_MODULE := gtest
|
LOCAL_MODULE := gtest
|
||||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/third_party/googletest/src/
|
LOCAL_C_INCLUDES := $(LOCAL_PATH)/third_party/googletest/src/
|
||||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/third_party/googletest/src/include/
|
LOCAL_C_INCLUDES += $(LOCAL_PATH)/third_party/googletest/src/include/
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/third_party/googletest/src/include/
|
|
||||||
LOCAL_SRC_FILES := ./third_party/googletest/src/src/gtest-all.cc
|
LOCAL_SRC_FILES := ./third_party/googletest/src/src/gtest-all.cc
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,22 @@ class AqSegmentTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DoTest(int aq_mode) {
|
||||||
|
aq_mode_ = aq_mode;
|
||||||
|
cfg_.kf_max_dist = 12;
|
||||||
|
cfg_.rc_min_quantizer = 8;
|
||||||
|
cfg_.rc_max_quantizer = 56;
|
||||||
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
|
cfg_.g_lag_in_frames = 6;
|
||||||
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
|
cfg_.rc_buf_optimal_sz = 500;
|
||||||
|
cfg_.rc_buf_sz = 1000;
|
||||||
|
cfg_.rc_target_bitrate = 300;
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv",
|
||||||
|
352, 288, 30, 1, 0, 15);
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
}
|
||||||
|
|
||||||
int set_cpu_used_;
|
int set_cpu_used_;
|
||||||
int aq_mode_;
|
int aq_mode_;
|
||||||
};
|
};
|
||||||
@@ -45,65 +61,42 @@ class AqSegmentTest
|
|||||||
// Validate that this AQ segmentation mode (AQ=1, variance_ap)
|
// Validate that this AQ segmentation mode (AQ=1, variance_ap)
|
||||||
// encodes and decodes without a mismatch.
|
// encodes and decodes without a mismatch.
|
||||||
TEST_P(AqSegmentTest, TestNoMisMatchAQ1) {
|
TEST_P(AqSegmentTest, TestNoMisMatchAQ1) {
|
||||||
cfg_.rc_min_quantizer = 8;
|
DoTest(1);
|
||||||
cfg_.rc_max_quantizer = 56;
|
|
||||||
cfg_.rc_end_usage = VPX_CBR;
|
|
||||||
cfg_.g_lag_in_frames = 0;
|
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
|
||||||
cfg_.rc_buf_sz = 1000;
|
|
||||||
cfg_.rc_target_bitrate = 300;
|
|
||||||
|
|
||||||
aq_mode_ = 1;
|
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
|
||||||
30, 1, 0, 100);
|
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate that this AQ segmentation mode (AQ=2, complexity_aq)
|
// Validate that this AQ segmentation mode (AQ=2, complexity_aq)
|
||||||
// encodes and decodes without a mismatch.
|
// encodes and decodes without a mismatch.
|
||||||
TEST_P(AqSegmentTest, TestNoMisMatchAQ2) {
|
TEST_P(AqSegmentTest, TestNoMisMatchAQ2) {
|
||||||
cfg_.rc_min_quantizer = 8;
|
DoTest(2);
|
||||||
cfg_.rc_max_quantizer = 56;
|
|
||||||
cfg_.rc_end_usage = VPX_CBR;
|
|
||||||
cfg_.g_lag_in_frames = 0;
|
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
|
||||||
cfg_.rc_buf_sz = 1000;
|
|
||||||
cfg_.rc_target_bitrate = 300;
|
|
||||||
|
|
||||||
aq_mode_ = 2;
|
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
|
||||||
30, 1, 0, 100);
|
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate that this AQ segmentation mode (AQ=3, cyclic_refresh_aq)
|
// Validate that this AQ segmentation mode (AQ=3, cyclic_refresh_aq)
|
||||||
// encodes and decodes without a mismatch.
|
// encodes and decodes without a mismatch.
|
||||||
TEST_P(AqSegmentTest, TestNoMisMatchAQ3) {
|
TEST_P(AqSegmentTest, TestNoMisMatchAQ3) {
|
||||||
cfg_.rc_min_quantizer = 8;
|
DoTest(3);
|
||||||
cfg_.rc_max_quantizer = 56;
|
|
||||||
cfg_.rc_end_usage = VPX_CBR;
|
|
||||||
cfg_.g_lag_in_frames = 0;
|
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
|
||||||
cfg_.rc_buf_sz = 1000;
|
|
||||||
cfg_.rc_target_bitrate = 300;
|
|
||||||
|
|
||||||
aq_mode_ = 3;
|
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
|
||||||
30, 1, 0, 100);
|
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(AqSegmentTest,
|
class AqSegmentTestLarge : public AqSegmentTest {};
|
||||||
|
|
||||||
|
TEST_P(AqSegmentTestLarge, TestNoMisMatchAQ1) {
|
||||||
|
DoTest(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(AqSegmentTestLarge, TestNoMisMatchAQ2) {
|
||||||
|
DoTest(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(AqSegmentTestLarge, TestNoMisMatchAQ3) {
|
||||||
|
DoTest(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VP10_INSTANTIATE_TEST_CASE(AqSegmentTest,
|
||||||
::testing::Values(::libvpx_test::kRealTime,
|
::testing::Values(::libvpx_test::kRealTime,
|
||||||
::libvpx_test::kOnePassGood),
|
::libvpx_test::kOnePassGood),
|
||||||
::testing::Range(3, 9));
|
::testing::Range(5, 9));
|
||||||
|
VP10_INSTANTIATE_TEST_CASE(AqSegmentTestLarge,
|
||||||
|
::testing::Values(::libvpx_test::kRealTime,
|
||||||
|
::libvpx_test::kOnePassGood),
|
||||||
|
::testing::Range(3, 5));
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
#include "test/y4m_video_source.h"
|
#include "test/y4m_video_source.h"
|
||||||
#include "test/yuv_video_source.h"
|
#include "test/yuv_video_source.h"
|
||||||
#include "vp9/encoder/vp9_ratectrl.h"
|
#include "vp10/encoder/ratectrl.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@@ -44,20 +44,24 @@ typedef struct {
|
|||||||
|
|
||||||
const TestVideoParam kTestVectors[] = {
|
const TestVideoParam kTestVectors[] = {
|
||||||
// artificially increase framerate to trigger default check
|
// artificially increase framerate to trigger default check
|
||||||
{ "hantro_collage_w352h288.yuv", 352, 288, 5000, 1, 8, VPX_IMG_FMT_I420,
|
{"hantro_collage_w352h288.yuv", 352, 288, 5000, 1,
|
||||||
VPX_BITS_8, 0 },
|
8, VPX_IMG_FMT_I420, VPX_BITS_8, 0},
|
||||||
{ "hantro_collage_w352h288.yuv", 352, 288, 30, 1, 8, VPX_IMG_FMT_I420,
|
{"hantro_collage_w352h288.yuv", 352, 288, 30, 1,
|
||||||
VPX_BITS_8, 0 },
|
8, VPX_IMG_FMT_I420, VPX_BITS_8, 0},
|
||||||
{ "rush_hour_444.y4m", 352, 288, 30, 1, 8, VPX_IMG_FMT_I444, VPX_BITS_8, 1 },
|
{"rush_hour_444.y4m", 352, 288, 30, 1,
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
8, VPX_IMG_FMT_I444, VPX_BITS_8, 1},
|
||||||
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
// Add list of profile 2/3 test videos here ...
|
// Add list of profile 2/3 test videos here ...
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
};
|
};
|
||||||
|
|
||||||
const TestEncodeParam kEncodeVectors[] = {
|
const TestEncodeParam kEncodeVectors[] = {
|
||||||
{ ::libvpx_test::kOnePassGood, 2 }, { ::libvpx_test::kOnePassGood, 5 },
|
{::libvpx_test::kOnePassGood, 2},
|
||||||
{ ::libvpx_test::kTwoPassGood, 1 }, { ::libvpx_test::kTwoPassGood, 2 },
|
{::libvpx_test::kOnePassGood, 5},
|
||||||
{ ::libvpx_test::kTwoPassGood, 5 }, { ::libvpx_test::kRealTime, 5 },
|
{::libvpx_test::kTwoPassGood, 1},
|
||||||
|
{::libvpx_test::kTwoPassGood, 2},
|
||||||
|
{::libvpx_test::kTwoPassGood, 5},
|
||||||
|
{::libvpx_test::kRealTime, 5},
|
||||||
};
|
};
|
||||||
|
|
||||||
const int kMinArfVectors[] = {
|
const int kMinArfVectors[] = {
|
||||||
@@ -68,23 +72,25 @@ const int kMinArfVectors[] = {
|
|||||||
|
|
||||||
int is_extension_y4m(const char *filename) {
|
int is_extension_y4m(const char *filename) {
|
||||||
const char *dot = strrchr(filename, '.');
|
const char *dot = strrchr(filename, '.');
|
||||||
if (!dot || dot == filename) {
|
if (!dot || dot == filename)
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
else
|
||||||
return !strcmp(dot, ".y4m");
|
return !strcmp(dot, ".y4m");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class ArfFreqTest
|
class ArfFreqTestLarge
|
||||||
: public ::libvpx_test::EncoderTest,
|
: public ::libvpx_test::EncoderTest,
|
||||||
public ::libvpx_test::CodecTestWith3Params<TestVideoParam,
|
public ::libvpx_test::CodecTestWith3Params<TestVideoParam, \
|
||||||
TestEncodeParam, int> {
|
TestEncodeParam, int> {
|
||||||
protected:
|
protected:
|
||||||
ArfFreqTest()
|
ArfFreqTestLarge()
|
||||||
: EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(1)),
|
: EncoderTest(GET_PARAM(0)),
|
||||||
test_encode_param_(GET_PARAM(2)), min_arf_requested_(GET_PARAM(3)) {}
|
test_video_param_(GET_PARAM(1)),
|
||||||
|
test_encode_param_(GET_PARAM(2)),
|
||||||
|
min_arf_requested_(GET_PARAM(3)) {
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~ArfFreqTest() {}
|
virtual ~ArfFreqTestLarge() {}
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
InitializeConfig();
|
InitializeConfig();
|
||||||
@@ -117,7 +123,8 @@ class ArfFreqTest
|
|||||||
// Assume superframe has only one visible frame, the rest being
|
// Assume superframe has only one visible frame, the rest being
|
||||||
// invisible. If superframe index is not found, then there is only
|
// invisible. If superframe index is not found, then there is only
|
||||||
// one frame.
|
// one frame.
|
||||||
if (!((marker & 0xe0) == 0xc0 && pkt->data.frame.sz >= index_sz &&
|
if (!((marker & 0xe0) == 0xc0 &&
|
||||||
|
pkt->data.frame.sz >= index_sz &&
|
||||||
buffer[pkt->data.frame.sz - index_sz] == marker)) {
|
buffer[pkt->data.frame.sz - index_sz] == marker)) {
|
||||||
frames = 1;
|
frames = 1;
|
||||||
}
|
}
|
||||||
@@ -125,7 +132,8 @@ class ArfFreqTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||||
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return;
|
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT)
|
||||||
|
return;
|
||||||
const int frames = GetNumFramesInPkt(pkt);
|
const int frames = GetNumFramesInPkt(pkt);
|
||||||
if (frames == 1) {
|
if (frames == 1) {
|
||||||
run_of_visible_frames_++;
|
run_of_visible_frames_++;
|
||||||
@@ -159,18 +167,19 @@ class ArfFreqTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetMinVisibleRun() const { return min_run_; }
|
int GetMinVisibleRun() const {
|
||||||
|
return min_run_;
|
||||||
|
}
|
||||||
|
|
||||||
int GetMinArfDistanceRequested() const {
|
int GetMinArfDistanceRequested() const {
|
||||||
if (min_arf_requested_) {
|
if (min_arf_requested_)
|
||||||
return min_arf_requested_;
|
return min_arf_requested_;
|
||||||
} else {
|
else
|
||||||
return vp9_rc_get_default_min_gf_interval(
|
return vp10_rc_get_default_min_gf_interval(
|
||||||
test_video_param_.width, test_video_param_.height,
|
test_video_param_.width, test_video_param_.height,
|
||||||
(double)test_video_param_.framerate_num /
|
(double)test_video_param_.framerate_num /
|
||||||
test_video_param_.framerate_den);
|
test_video_param_.framerate_den);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
TestVideoParam test_video_param_;
|
TestVideoParam test_video_param_;
|
||||||
TestEncodeParam test_encode_param_;
|
TestEncodeParam test_encode_param_;
|
||||||
@@ -181,25 +190,28 @@ class ArfFreqTest
|
|||||||
int run_of_visible_frames_;
|
int run_of_visible_frames_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(ArfFreqTest, MinArfFreqTest) {
|
TEST_P(ArfFreqTestLarge, MinArfFreqTest) {
|
||||||
cfg_.rc_target_bitrate = kBitrate;
|
cfg_.rc_target_bitrate = kBitrate;
|
||||||
cfg_.g_error_resilient = 0;
|
cfg_.g_error_resilient = 0;
|
||||||
cfg_.g_profile = test_video_param_.profile;
|
cfg_.g_profile = test_video_param_.profile;
|
||||||
cfg_.g_input_bit_depth = test_video_param_.input_bit_depth;
|
cfg_.g_input_bit_depth = test_video_param_.input_bit_depth;
|
||||||
cfg_.g_bit_depth = test_video_param_.bit_depth;
|
cfg_.g_bit_depth = test_video_param_.bit_depth;
|
||||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||||
if (cfg_.g_bit_depth > 8) init_flags_ |= VPX_CODEC_USE_HIGHBITDEPTH;
|
if (cfg_.g_bit_depth > 8)
|
||||||
|
init_flags_ |= VPX_CODEC_USE_HIGHBITDEPTH;
|
||||||
|
|
||||||
testing::internal::scoped_ptr<libvpx_test::VideoSource> video;
|
testing::internal::scoped_ptr<libvpx_test::VideoSource> video;
|
||||||
if (is_extension_y4m(test_video_param_.filename)) {
|
if (is_extension_y4m(test_video_param_.filename)) {
|
||||||
video.reset(new libvpx_test::Y4mVideoSource(test_video_param_.filename, 0,
|
video.reset(new libvpx_test::Y4mVideoSource(test_video_param_.filename,
|
||||||
kFrames));
|
0, kFrames));
|
||||||
} else {
|
} else {
|
||||||
video.reset(new libvpx_test::YUVVideoSource(
|
video.reset(new libvpx_test::YUVVideoSource(test_video_param_.filename,
|
||||||
test_video_param_.filename, test_video_param_.fmt,
|
test_video_param_.fmt,
|
||||||
test_video_param_.width, test_video_param_.height,
|
test_video_param_.width,
|
||||||
test_video_param_.framerate_num, test_video_param_.framerate_den, 0,
|
test_video_param_.height,
|
||||||
kFrames));
|
test_video_param_.framerate_num,
|
||||||
|
test_video_param_.framerate_den,
|
||||||
|
0, kFrames));
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
||||||
@@ -211,7 +223,27 @@ TEST_P(ArfFreqTest, MinArfFreqTest) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(ArfFreqTest, ::testing::ValuesIn(kTestVectors),
|
#if CONFIG_VPX_HIGHBITDEPTH || CONFIG_EXT_REFS
|
||||||
|
#if CONFIG_VP10_ENCODER
|
||||||
|
// TODO(angiebird): 25-29 fail in high bitdepth mode.
|
||||||
|
// TODO(zoeliu): This ArfFreqTest does not work with BWDREF_FRAME, as
|
||||||
|
// BWDREF_FRAME is also a non-show frame, and the minimum run between two
|
||||||
|
// consecutive BWDREF_FRAME's may vary between 1 and any arbitrary positive
|
||||||
|
// number as long as it does not exceed the gf_group interval.
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
DISABLED_VP10, ArfFreqTestLarge,
|
||||||
|
::testing::Combine(
|
||||||
|
::testing::Values(static_cast<const libvpx_test::CodecFactory *>(
|
||||||
|
&libvpx_test::kVP10)),
|
||||||
|
::testing::ValuesIn(kTestVectors),
|
||||||
|
::testing::ValuesIn(kEncodeVectors),
|
||||||
|
::testing::ValuesIn(kMinArfVectors)));
|
||||||
|
#endif // CONFIG_VP10_ENCODER
|
||||||
|
#else
|
||||||
|
VP10_INSTANTIATE_TEST_CASE(
|
||||||
|
ArfFreqTestLarge,
|
||||||
|
::testing::ValuesIn(kTestVectors),
|
||||||
::testing::ValuesIn(kEncodeVectors),
|
::testing::ValuesIn(kEncodeVectors),
|
||||||
::testing::ValuesIn(kMinArfVectors));
|
::testing::ValuesIn(kMinArfVectors));
|
||||||
|
#endif // CONFIG_VPX_HIGHBITDEPTH || CONFIG_EXT_REFS
|
||||||
} // namespace
|
} // namespace
|
||||||
314
test/avg_test.cc
314
test/avg_test.cc
@@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vp9_rtcd.h"
|
|
||||||
#include "./vpx_config.h"
|
#include "./vpx_config.h"
|
||||||
#include "./vpx_dsp_rtcd.h"
|
#include "./vpx_dsp_rtcd.h"
|
||||||
|
|
||||||
@@ -23,7 +22,6 @@
|
|||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
#include "vpx_mem/vpx_mem.h"
|
#include "vpx_mem/vpx_mem.h"
|
||||||
#include "vpx_ports/vpx_timer.h"
|
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
@@ -42,7 +40,9 @@ class AverageTestBase : public ::testing::Test {
|
|||||||
source_data_ = NULL;
|
source_data_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
virtual void TearDown() {
|
||||||
|
libvpx_test::ClearSystemState();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Handle blocks up to 4 blocks 64x64 with stride up to 128
|
// Handle blocks up to 4 blocks 64x64 with stride up to 128
|
||||||
@@ -55,19 +55,19 @@ class AverageTestBase : public ::testing::Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sum Pixels
|
// Sum Pixels
|
||||||
static unsigned int ReferenceAverage8x8(const uint8_t *source, int pitch) {
|
unsigned int ReferenceAverage8x8(const uint8_t* source, int pitch) {
|
||||||
unsigned int average = 0;
|
unsigned int average = 0;
|
||||||
for (int h = 0; h < 8; ++h) {
|
for (int h = 0; h < 8; ++h)
|
||||||
for (int w = 0; w < 8; ++w) average += source[h * pitch + w];
|
for (int w = 0; w < 8; ++w)
|
||||||
}
|
average += source[h * pitch + w];
|
||||||
return ((average + 32) >> 6);
|
return ((average + 32) >> 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int ReferenceAverage4x4(const uint8_t *source, int pitch) {
|
unsigned int ReferenceAverage4x4(const uint8_t* source, int pitch) {
|
||||||
unsigned int average = 0;
|
unsigned int average = 0;
|
||||||
for (int h = 0; h < 4; ++h) {
|
for (int h = 0; h < 4; ++h)
|
||||||
for (int w = 0; w < 4; ++w) average += source[h * pitch + w];
|
for (int w = 0; w < 4; ++w)
|
||||||
}
|
average += source[h * pitch + w];
|
||||||
return ((average + 8) >> 4);
|
return ((average + 8) >> 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,27 +93,27 @@ typedef unsigned int (*AverageFunction)(const uint8_t *s, int pitch);
|
|||||||
|
|
||||||
typedef std::tr1::tuple<int, int, int, int, AverageFunction> AvgFunc;
|
typedef std::tr1::tuple<int, int, int, int, AverageFunction> AvgFunc;
|
||||||
|
|
||||||
class AverageTest : public AverageTestBase,
|
class AverageTest
|
||||||
|
: public AverageTestBase,
|
||||||
public ::testing::WithParamInterface<AvgFunc>{
|
public ::testing::WithParamInterface<AvgFunc>{
|
||||||
public:
|
public:
|
||||||
AverageTest() : AverageTestBase(GET_PARAM(0), GET_PARAM(1)) {}
|
AverageTest() : AverageTestBase(GET_PARAM(0), GET_PARAM(1)) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void CheckAverages() {
|
void CheckAverages() {
|
||||||
const int block_size = GET_PARAM(3);
|
|
||||||
unsigned int expected = 0;
|
unsigned int expected = 0;
|
||||||
if (block_size == 8) {
|
if (GET_PARAM(3) == 8) {
|
||||||
expected =
|
expected = ReferenceAverage8x8(source_data_+ GET_PARAM(2),
|
||||||
ReferenceAverage8x8(source_data_ + GET_PARAM(2), source_stride_);
|
source_stride_);
|
||||||
} else if (block_size == 4) {
|
} else if (GET_PARAM(3) == 4) {
|
||||||
expected =
|
expected = ReferenceAverage4x4(source_data_+ GET_PARAM(2),
|
||||||
ReferenceAverage4x4(source_data_ + GET_PARAM(2), source_stride_);
|
source_stride_);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(GET_PARAM(4)(source_data_+ GET_PARAM(2),
|
||||||
GET_PARAM(4)(source_data_ + GET_PARAM(2), source_stride_));
|
source_stride_));
|
||||||
unsigned int actual =
|
unsigned int actual = GET_PARAM(4)(source_data_+ GET_PARAM(2),
|
||||||
GET_PARAM(4)(source_data_ + GET_PARAM(2), source_stride_);
|
source_stride_);
|
||||||
|
|
||||||
EXPECT_EQ(expected, actual);
|
EXPECT_EQ(expected, actual);
|
||||||
}
|
}
|
||||||
@@ -124,11 +124,14 @@ typedef void (*IntProRowFunc)(int16_t hbuf[16], uint8_t const *ref,
|
|||||||
|
|
||||||
typedef std::tr1::tuple<int, IntProRowFunc, IntProRowFunc> IntProRowParam;
|
typedef std::tr1::tuple<int, IntProRowFunc, IntProRowFunc> IntProRowParam;
|
||||||
|
|
||||||
class IntProRowTest : public AverageTestBase,
|
class IntProRowTest
|
||||||
|
: public AverageTestBase,
|
||||||
public ::testing::WithParamInterface<IntProRowParam> {
|
public ::testing::WithParamInterface<IntProRowParam> {
|
||||||
public:
|
public:
|
||||||
IntProRowTest()
|
IntProRowTest()
|
||||||
: AverageTestBase(16, GET_PARAM(0)), hbuf_asm_(NULL), hbuf_c_(NULL) {
|
: AverageTestBase(16, GET_PARAM(0)),
|
||||||
|
hbuf_asm_(NULL),
|
||||||
|
hbuf_c_(NULL) {
|
||||||
asm_func_ = GET_PARAM(1);
|
asm_func_ = GET_PARAM(1);
|
||||||
c_func_ = GET_PARAM(2);
|
c_func_ = GET_PARAM(2);
|
||||||
}
|
}
|
||||||
@@ -166,7 +169,8 @@ typedef int16_t (*IntProColFunc)(uint8_t const *ref, const int width);
|
|||||||
|
|
||||||
typedef std::tr1::tuple<int, IntProColFunc, IntProColFunc> IntProColParam;
|
typedef std::tr1::tuple<int, IntProColFunc, IntProColFunc> IntProColParam;
|
||||||
|
|
||||||
class IntProColTest : public AverageTestBase,
|
class IntProColTest
|
||||||
|
: public AverageTestBase,
|
||||||
public ::testing::WithParamInterface<IntProColParam> {
|
public ::testing::WithParamInterface<IntProColParam> {
|
||||||
public:
|
public:
|
||||||
IntProColTest() : AverageTestBase(GET_PARAM(0), 1), sum_asm_(0), sum_c_(0) {
|
IntProColTest() : AverageTestBase(GET_PARAM(0), 1), sum_asm_(0), sum_c_(0) {
|
||||||
@@ -188,17 +192,18 @@ class IntProColTest : public AverageTestBase,
|
|||||||
int16_t sum_c_;
|
int16_t sum_c_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*SatdFunc)(const tran_low_t *coeffs, int length);
|
typedef int (*SatdFunc)(const int16_t *coeffs, int length);
|
||||||
typedef std::tr1::tuple<int, SatdFunc> SatdTestParam;
|
typedef std::tr1::tuple<int, SatdFunc> SatdTestParam;
|
||||||
|
|
||||||
class SatdTest : public ::testing::Test,
|
class SatdTest
|
||||||
|
: public ::testing::Test,
|
||||||
public ::testing::WithParamInterface<SatdTestParam> {
|
public ::testing::WithParamInterface<SatdTestParam> {
|
||||||
protected:
|
protected:
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
satd_size_ = GET_PARAM(0);
|
satd_size_ = GET_PARAM(0);
|
||||||
satd_func_ = GET_PARAM(1);
|
satd_func_ = GET_PARAM(1);
|
||||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||||
src_ = reinterpret_cast<tran_low_t *>(
|
src_ = reinterpret_cast<int16_t*>(
|
||||||
vpx_memalign(16, sizeof(*src_) * satd_size_));
|
vpx_memalign(16, sizeof(*src_) * satd_size_));
|
||||||
ASSERT_TRUE(src_ != NULL);
|
ASSERT_TRUE(src_ != NULL);
|
||||||
}
|
}
|
||||||
@@ -208,15 +213,12 @@ class SatdTest : public ::testing::Test,
|
|||||||
vpx_free(src_);
|
vpx_free(src_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FillConstant(const tran_low_t val) {
|
void FillConstant(const int16_t val) {
|
||||||
for (int i = 0; i < satd_size_; ++i) src_[i] = val;
|
for (int i = 0; i < satd_size_; ++i) src_[i] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FillRandom() {
|
void FillRandom() {
|
||||||
for (int i = 0; i < satd_size_; ++i) {
|
for (int i = 0; i < satd_size_; ++i) src_[i] = rnd_.Rand16();
|
||||||
const int16_t tmp = rnd_.Rand16();
|
|
||||||
src_[i] = (tran_low_t)tmp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Check(const int expected) {
|
void Check(const int expected) {
|
||||||
@@ -228,66 +230,11 @@ class SatdTest : public ::testing::Test,
|
|||||||
int satd_size_;
|
int satd_size_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
tran_low_t *src_;
|
int16_t *src_;
|
||||||
SatdFunc satd_func_;
|
SatdFunc satd_func_;
|
||||||
ACMRandom rnd_;
|
ACMRandom rnd_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int64_t (*BlockErrorFunc)(const tran_low_t *coeff,
|
|
||||||
const tran_low_t *dqcoeff, int block_size);
|
|
||||||
typedef std::tr1::tuple<int, BlockErrorFunc> BlockErrorTestFPParam;
|
|
||||||
|
|
||||||
class BlockErrorTestFP
|
|
||||||
: public ::testing::Test,
|
|
||||||
public ::testing::WithParamInterface<BlockErrorTestFPParam> {
|
|
||||||
protected:
|
|
||||||
virtual void SetUp() {
|
|
||||||
txfm_size_ = GET_PARAM(0);
|
|
||||||
block_error_func_ = GET_PARAM(1);
|
|
||||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
|
||||||
coeff_ = reinterpret_cast<tran_low_t *>(
|
|
||||||
vpx_memalign(16, sizeof(*coeff_) * txfm_size_));
|
|
||||||
dqcoeff_ = reinterpret_cast<tran_low_t *>(
|
|
||||||
vpx_memalign(16, sizeof(*dqcoeff_) * txfm_size_));
|
|
||||||
ASSERT_TRUE(coeff_ != NULL);
|
|
||||||
ASSERT_TRUE(dqcoeff_ != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void TearDown() {
|
|
||||||
libvpx_test::ClearSystemState();
|
|
||||||
vpx_free(coeff_);
|
|
||||||
vpx_free(dqcoeff_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FillConstant(const tran_low_t coeff_val, const tran_low_t dqcoeff_val) {
|
|
||||||
for (int i = 0; i < txfm_size_; ++i) coeff_[i] = coeff_val;
|
|
||||||
for (int i = 0; i < txfm_size_; ++i) dqcoeff_[i] = dqcoeff_val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FillRandom() {
|
|
||||||
// Just two fixed seeds
|
|
||||||
rnd_.Reset(0xb0b9);
|
|
||||||
for (int i = 0; i < txfm_size_; ++i) coeff_[i] = rnd_.Rand16() >> 1;
|
|
||||||
rnd_.Reset(0xb0c8);
|
|
||||||
for (int i = 0; i < txfm_size_; ++i) dqcoeff_[i] = rnd_.Rand16() >> 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Check(const int64_t expected) {
|
|
||||||
int64_t total;
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
total = block_error_func_(coeff_, dqcoeff_, txfm_size_));
|
|
||||||
EXPECT_EQ(expected, total);
|
|
||||||
}
|
|
||||||
|
|
||||||
int txfm_size_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
tran_low_t *coeff_;
|
|
||||||
tran_low_t *dqcoeff_;
|
|
||||||
BlockErrorFunc block_error_func_;
|
|
||||||
ACMRandom rnd_;
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t* AverageTestBase::source_data_ = NULL;
|
uint8_t* AverageTestBase::source_data_ = NULL;
|
||||||
|
|
||||||
TEST_P(AverageTest, MinValue) {
|
TEST_P(AverageTest, MinValue) {
|
||||||
@@ -339,6 +286,7 @@ TEST_P(IntProColTest, Random) {
|
|||||||
RunComparison();
|
RunComparison();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_P(SatdTest, MinValue) {
|
TEST_P(SatdTest, MinValue) {
|
||||||
const int kMin = -32640;
|
const int kMin = -32640;
|
||||||
const int expected = -kMin * satd_size_;
|
const int expected = -kMin * satd_size_;
|
||||||
@@ -368,90 +316,27 @@ TEST_P(SatdTest, Random) {
|
|||||||
Check(expected);
|
Check(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(SatdTest, DISABLED_Speed) {
|
|
||||||
const int kCountSpeedTestBlock = 20000;
|
|
||||||
vpx_usec_timer timer;
|
|
||||||
DECLARE_ALIGNED(16, tran_low_t, coeff[1024]);
|
|
||||||
const int blocksize = GET_PARAM(0);
|
|
||||||
|
|
||||||
vpx_usec_timer_start(&timer);
|
|
||||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
|
||||||
GET_PARAM(1)(coeff, blocksize);
|
|
||||||
}
|
|
||||||
vpx_usec_timer_mark(&timer);
|
|
||||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
|
||||||
printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(BlockErrorTestFP, MinValue) {
|
|
||||||
const int64_t kMin = -32640;
|
|
||||||
const int64_t expected = kMin * kMin * txfm_size_;
|
|
||||||
FillConstant(kMin, 0);
|
|
||||||
Check(expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(BlockErrorTestFP, MaxValue) {
|
|
||||||
const int64_t kMax = 32640;
|
|
||||||
const int64_t expected = kMax * kMax * txfm_size_;
|
|
||||||
FillConstant(kMax, 0);
|
|
||||||
Check(expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(BlockErrorTestFP, Random) {
|
|
||||||
int64_t expected;
|
|
||||||
switch (txfm_size_) {
|
|
||||||
case 16: expected = 2051681432; break;
|
|
||||||
case 64: expected = 11075114379; break;
|
|
||||||
case 256: expected = 44386271116; break;
|
|
||||||
case 1024: expected = 184774996089; break;
|
|
||||||
default:
|
|
||||||
FAIL() << "Invalid satd size (" << txfm_size_
|
|
||||||
<< ") valid: 16/64/256/1024";
|
|
||||||
}
|
|
||||||
FillRandom();
|
|
||||||
Check(expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(BlockErrorTestFP, DISABLED_Speed) {
|
|
||||||
const int kCountSpeedTestBlock = 20000;
|
|
||||||
vpx_usec_timer timer;
|
|
||||||
DECLARE_ALIGNED(16, tran_low_t, coeff[1024]);
|
|
||||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[1024]);
|
|
||||||
const int blocksize = GET_PARAM(0);
|
|
||||||
|
|
||||||
vpx_usec_timer_start(&timer);
|
|
||||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
|
||||||
GET_PARAM(1)(coeff, dqcoeff, blocksize);
|
|
||||||
}
|
|
||||||
vpx_usec_timer_mark(&timer);
|
|
||||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
|
||||||
printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
using std::tr1::make_tuple;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, AverageTest,
|
C, AverageTest,
|
||||||
::testing::Values(make_tuple(16, 16, 1, 8, &vpx_avg_8x8_c),
|
::testing::Values(
|
||||||
|
make_tuple(16, 16, 1, 8, &vpx_avg_8x8_c),
|
||||||
make_tuple(16, 16, 1, 4, &vpx_avg_4x4_c)));
|
make_tuple(16, 16, 1, 4, &vpx_avg_4x4_c)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(C, SatdTest,
|
INSTANTIATE_TEST_CASE_P(
|
||||||
::testing::Values(make_tuple(16, &vpx_satd_c),
|
C, SatdTest,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(16, &vpx_satd_c),
|
||||||
make_tuple(64, &vpx_satd_c),
|
make_tuple(64, &vpx_satd_c),
|
||||||
make_tuple(256, &vpx_satd_c),
|
make_tuple(256, &vpx_satd_c),
|
||||||
make_tuple(1024, &vpx_satd_c)));
|
make_tuple(1024, &vpx_satd_c)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
C, BlockErrorTestFP,
|
|
||||||
::testing::Values(make_tuple(16, &vp9_block_error_fp_c),
|
|
||||||
make_tuple(64, &vp9_block_error_fp_c),
|
|
||||||
make_tuple(256, &vp9_block_error_fp_c),
|
|
||||||
make_tuple(1024, &vp9_block_error_fp_c)));
|
|
||||||
|
|
||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, AverageTest,
|
SSE2, AverageTest,
|
||||||
::testing::Values(make_tuple(16, 16, 0, 8, &vpx_avg_8x8_sse2),
|
::testing::Values(
|
||||||
|
make_tuple(16, 16, 0, 8, &vpx_avg_8x8_sse2),
|
||||||
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_sse2),
|
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_sse2),
|
||||||
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_sse2),
|
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_sse2),
|
||||||
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_sse2),
|
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_sse2),
|
||||||
@@ -459,52 +344,31 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_sse2)));
|
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_sse2)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, IntProRowTest,
|
SSE2, IntProRowTest, ::testing::Values(
|
||||||
::testing::Values(make_tuple(16, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c),
|
make_tuple(16, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c),
|
||||||
make_tuple(32, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c),
|
make_tuple(32, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c),
|
||||||
make_tuple(64, &vpx_int_pro_row_sse2,
|
make_tuple(64, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c)));
|
||||||
&vpx_int_pro_row_c)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, IntProColTest,
|
SSE2, IntProColTest, ::testing::Values(
|
||||||
::testing::Values(make_tuple(16, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c),
|
make_tuple(16, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c),
|
||||||
make_tuple(32, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c),
|
make_tuple(32, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c),
|
||||||
make_tuple(64, &vpx_int_pro_col_sse2,
|
make_tuple(64, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c)));
|
||||||
&vpx_int_pro_col_c)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, SatdTest,
|
INSTANTIATE_TEST_CASE_P(
|
||||||
::testing::Values(make_tuple(16, &vpx_satd_sse2),
|
SSE2, SatdTest,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(16, &vpx_satd_sse2),
|
||||||
make_tuple(64, &vpx_satd_sse2),
|
make_tuple(64, &vpx_satd_sse2),
|
||||||
make_tuple(256, &vpx_satd_sse2),
|
make_tuple(256, &vpx_satd_sse2),
|
||||||
make_tuple(1024, &vpx_satd_sse2)));
|
make_tuple(1024, &vpx_satd_sse2)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE2, BlockErrorTestFP,
|
|
||||||
::testing::Values(make_tuple(16, &vp9_block_error_fp_sse2),
|
|
||||||
make_tuple(64, &vp9_block_error_fp_sse2),
|
|
||||||
make_tuple(256, &vp9_block_error_fp_sse2),
|
|
||||||
make_tuple(1024, &vp9_block_error_fp_sse2)));
|
|
||||||
#endif // HAVE_SSE2
|
|
||||||
|
|
||||||
#if HAVE_AVX2
|
|
||||||
INSTANTIATE_TEST_CASE_P(AVX2, SatdTest,
|
|
||||||
::testing::Values(make_tuple(16, &vpx_satd_avx2),
|
|
||||||
make_tuple(64, &vpx_satd_avx2),
|
|
||||||
make_tuple(256, &vpx_satd_avx2),
|
|
||||||
make_tuple(1024, &vpx_satd_avx2)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
AVX2, BlockErrorTestFP,
|
|
||||||
::testing::Values(make_tuple(16, &vp9_block_error_fp_avx2),
|
|
||||||
make_tuple(64, &vp9_block_error_fp_avx2),
|
|
||||||
make_tuple(256, &vp9_block_error_fp_avx2),
|
|
||||||
make_tuple(1024, &vp9_block_error_fp_avx2)));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_NEON
|
#if HAVE_NEON
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, AverageTest,
|
NEON, AverageTest,
|
||||||
::testing::Values(make_tuple(16, 16, 0, 8, &vpx_avg_8x8_neon),
|
::testing::Values(
|
||||||
|
make_tuple(16, 16, 0, 8, &vpx_avg_8x8_neon),
|
||||||
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_neon),
|
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_neon),
|
||||||
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_neon),
|
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_neon),
|
||||||
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_neon),
|
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_neon),
|
||||||
@@ -512,70 +376,36 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_neon)));
|
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_neon)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, IntProRowTest,
|
NEON, IntProRowTest, ::testing::Values(
|
||||||
::testing::Values(make_tuple(16, &vpx_int_pro_row_neon, &vpx_int_pro_row_c),
|
make_tuple(16, &vpx_int_pro_row_neon, &vpx_int_pro_row_c),
|
||||||
make_tuple(32, &vpx_int_pro_row_neon, &vpx_int_pro_row_c),
|
make_tuple(32, &vpx_int_pro_row_neon, &vpx_int_pro_row_c),
|
||||||
make_tuple(64, &vpx_int_pro_row_neon,
|
make_tuple(64, &vpx_int_pro_row_neon, &vpx_int_pro_row_c)));
|
||||||
&vpx_int_pro_row_c)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, IntProColTest,
|
NEON, IntProColTest, ::testing::Values(
|
||||||
::testing::Values(make_tuple(16, &vpx_int_pro_col_neon, &vpx_int_pro_col_c),
|
make_tuple(16, &vpx_int_pro_col_neon, &vpx_int_pro_col_c),
|
||||||
make_tuple(32, &vpx_int_pro_col_neon, &vpx_int_pro_col_c),
|
make_tuple(32, &vpx_int_pro_col_neon, &vpx_int_pro_col_c),
|
||||||
make_tuple(64, &vpx_int_pro_col_neon,
|
make_tuple(64, &vpx_int_pro_col_neon, &vpx_int_pro_col_c)));
|
||||||
&vpx_int_pro_col_c)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(NEON, SatdTest,
|
INSTANTIATE_TEST_CASE_P(
|
||||||
::testing::Values(make_tuple(16, &vpx_satd_neon),
|
NEON, SatdTest,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(16, &vpx_satd_neon),
|
||||||
make_tuple(64, &vpx_satd_neon),
|
make_tuple(64, &vpx_satd_neon),
|
||||||
make_tuple(256, &vpx_satd_neon),
|
make_tuple(256, &vpx_satd_neon),
|
||||||
make_tuple(1024, &vpx_satd_neon)));
|
make_tuple(1024, &vpx_satd_neon)));
|
||||||
|
#endif
|
||||||
// TODO(jianj): Remove the highbitdepth flag once the SIMD functions are
|
|
||||||
// in place.
|
|
||||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
NEON, BlockErrorTestFP,
|
|
||||||
::testing::Values(make_tuple(16, &vp9_block_error_fp_neon),
|
|
||||||
make_tuple(64, &vp9_block_error_fp_neon),
|
|
||||||
make_tuple(256, &vp9_block_error_fp_neon),
|
|
||||||
make_tuple(1024, &vp9_block_error_fp_neon)));
|
|
||||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
#endif // HAVE_NEON
|
|
||||||
|
|
||||||
#if HAVE_MSA
|
#if HAVE_MSA
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
MSA, AverageTest,
|
MSA, AverageTest,
|
||||||
::testing::Values(make_tuple(16, 16, 0, 8, &vpx_avg_8x8_msa),
|
::testing::Values(
|
||||||
|
make_tuple(16, 16, 0, 8, &vpx_avg_8x8_msa),
|
||||||
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_msa),
|
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_msa),
|
||||||
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_msa),
|
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_msa),
|
||||||
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_msa),
|
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_msa),
|
||||||
make_tuple(16, 16, 5, 4, &vpx_avg_4x4_msa),
|
make_tuple(16, 16, 5, 4, &vpx_avg_4x4_msa),
|
||||||
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_msa)));
|
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_msa)));
|
||||||
|
#endif
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MSA, IntProRowTest,
|
|
||||||
::testing::Values(make_tuple(16, &vpx_int_pro_row_msa, &vpx_int_pro_row_c),
|
|
||||||
make_tuple(32, &vpx_int_pro_row_msa, &vpx_int_pro_row_c),
|
|
||||||
make_tuple(64, &vpx_int_pro_row_msa,
|
|
||||||
&vpx_int_pro_row_c)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MSA, IntProColTest,
|
|
||||||
::testing::Values(make_tuple(16, &vpx_int_pro_col_msa, &vpx_int_pro_col_c),
|
|
||||||
make_tuple(32, &vpx_int_pro_col_msa, &vpx_int_pro_col_c),
|
|
||||||
make_tuple(64, &vpx_int_pro_col_msa,
|
|
||||||
&vpx_int_pro_col_c)));
|
|
||||||
|
|
||||||
// TODO(jingning): Remove the highbitdepth flag once the SIMD functions are
|
|
||||||
// in place.
|
|
||||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
INSTANTIATE_TEST_CASE_P(MSA, SatdTest,
|
|
||||||
::testing::Values(make_tuple(16, &vpx_satd_msa),
|
|
||||||
make_tuple(64, &vpx_satd_msa),
|
|
||||||
make_tuple(256, &vpx_satd_msa),
|
|
||||||
make_tuple(1024, &vpx_satd_msa)));
|
|
||||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
#endif // HAVE_MSA
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
367
test/blend_a64_mask_1d_test.cc
Normal file
367
test/blend_a64_mask_1d_test.cc
Normal file
@@ -0,0 +1,367 @@
|
|||||||
|
/*
|
||||||
|
* 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 <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
#include "test/register_state_check.h"
|
||||||
|
|
||||||
|
#include "test/function_equivalence_test.h"
|
||||||
|
|
||||||
|
#include "./vpx_config.h"
|
||||||
|
#include "./vpx_dsp_rtcd.h"
|
||||||
|
#include "vpx/vpx_integer.h"
|
||||||
|
|
||||||
|
#include "./vp10_rtcd.h"
|
||||||
|
|
||||||
|
#include "vp10/common/enums.h"
|
||||||
|
|
||||||
|
#include "vpx_dsp/blend.h"
|
||||||
|
|
||||||
|
using libvpx_test::FunctionEquivalenceTest;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template<typename F, typename T>
|
||||||
|
class BlendA64Mask1DTest : public FunctionEquivalenceTest<F> {
|
||||||
|
public:
|
||||||
|
static const int kIterations = 10000;
|
||||||
|
static const int kMaxWidth = MAX_SB_SIZE * 5; // * 5 to cover longer strides
|
||||||
|
static const int kMaxHeight = MAX_SB_SIZE;
|
||||||
|
static const int kBufSize = kMaxWidth * kMaxHeight;
|
||||||
|
static const int kMaxMaskWidth = 2 * MAX_SB_SIZE;
|
||||||
|
static const int kMaxMaskSize = kMaxMaskWidth;
|
||||||
|
|
||||||
|
virtual ~BlendA64Mask1DTest() {}
|
||||||
|
|
||||||
|
virtual void Execute(const T *p_src0, const T *p_src1) = 0;
|
||||||
|
|
||||||
|
void Common() {
|
||||||
|
w_ = 1 << this->rng_(MAX_SB_SIZE_LOG2 + 1);
|
||||||
|
h_ = 1 << this->rng_(MAX_SB_SIZE_LOG2 + 1);
|
||||||
|
|
||||||
|
dst_offset_ = this->rng_(33);
|
||||||
|
dst_stride_ = this->rng_(kMaxWidth + 1 - w_) + w_;
|
||||||
|
|
||||||
|
src0_offset_ = this->rng_(33);
|
||||||
|
src0_stride_ = this->rng_(kMaxWidth + 1 - w_) + w_;
|
||||||
|
|
||||||
|
src1_offset_ = this->rng_(33);
|
||||||
|
src1_stride_ = this->rng_(kMaxWidth + 1 - w_) + w_;
|
||||||
|
|
||||||
|
T *p_src0;
|
||||||
|
T *p_src1;
|
||||||
|
|
||||||
|
switch (this->rng_(3)) {
|
||||||
|
case 0: // Separate sources
|
||||||
|
p_src0 = src0_;
|
||||||
|
p_src1 = src1_;
|
||||||
|
break;
|
||||||
|
case 1: // src0 == dst
|
||||||
|
p_src0 = dst_tst_;
|
||||||
|
src0_stride_ = dst_stride_;
|
||||||
|
src0_offset_ = dst_offset_;
|
||||||
|
p_src1 = src1_;
|
||||||
|
break;
|
||||||
|
case 2: // src1 == dst
|
||||||
|
p_src0 = src0_;
|
||||||
|
p_src1 = dst_tst_;
|
||||||
|
src1_stride_ = dst_stride_;
|
||||||
|
src1_offset_ = dst_offset_;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
FAIL();
|
||||||
|
}
|
||||||
|
|
||||||
|
Execute(p_src0, p_src1);
|
||||||
|
|
||||||
|
for (int r = 0 ; r < h_ ; ++r) {
|
||||||
|
for (int c = 0 ; c < w_ ; ++c) {
|
||||||
|
ASSERT_EQ(dst_ref_[dst_offset_ + r * dst_stride_ + c],
|
||||||
|
dst_tst_[dst_offset_ + r * dst_stride_ + c]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T dst_ref_[kBufSize];
|
||||||
|
T dst_tst_[kBufSize];
|
||||||
|
size_t dst_stride_;
|
||||||
|
size_t dst_offset_;
|
||||||
|
|
||||||
|
T src0_[kBufSize];
|
||||||
|
size_t src0_stride_;
|
||||||
|
size_t src0_offset_;
|
||||||
|
|
||||||
|
T src1_[kBufSize];
|
||||||
|
size_t src1_stride_;
|
||||||
|
size_t src1_offset_;
|
||||||
|
|
||||||
|
uint8_t mask_[kMaxMaskSize];
|
||||||
|
|
||||||
|
int w_;
|
||||||
|
int h_;
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 8 bit version
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef void (*F8B)(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);
|
||||||
|
typedef libvpx_test::FuncParam<F8B> TestFuncs;
|
||||||
|
|
||||||
|
class BlendA64Mask1DTest8B : public BlendA64Mask1DTest<F8B, uint8_t> {
|
||||||
|
protected:
|
||||||
|
void Execute(const uint8_t *p_src0, const uint8_t *p_src1) {
|
||||||
|
params_.ref_func(dst_ref_ + dst_offset_, dst_stride_,
|
||||||
|
p_src0 + src0_offset_, src0_stride_,
|
||||||
|
p_src1 + src1_offset_, src1_stride_, mask_, h_, w_);
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
params_.tst_func(dst_tst_ + dst_offset_, dst_stride_,
|
||||||
|
p_src0 + src0_offset_, src0_stride_,
|
||||||
|
p_src1 + src1_offset_, src1_stride_, mask_, h_, w_));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(BlendA64Mask1DTest8B, RandomValues) {
|
||||||
|
for (int iter = 0 ; iter < kIterations && !HasFatalFailure(); ++iter) {
|
||||||
|
for (int i = 0 ; i < kBufSize ; ++i) {
|
||||||
|
dst_ref_[i] = rng_.Rand8();
|
||||||
|
dst_tst_[i] = rng_.Rand8();
|
||||||
|
|
||||||
|
src0_[i] = rng_.Rand8();
|
||||||
|
src1_[i] = rng_.Rand8();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < kMaxMaskSize ; ++i)
|
||||||
|
mask_[i] = rng_(VPX_BLEND_A64_MAX_ALPHA + 1);
|
||||||
|
|
||||||
|
Common();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(BlendA64Mask1DTest8B, ExtremeValues) {
|
||||||
|
for (int iter = 0 ; iter < kIterations && !HasFatalFailure(); ++iter) {
|
||||||
|
for (int i = 0 ; i < kBufSize ; ++i) {
|
||||||
|
dst_ref_[i] = rng_(2) + 254;
|
||||||
|
dst_tst_[i] = rng_(2) + 254;
|
||||||
|
src0_[i] = rng_(2) + 254;
|
||||||
|
src1_[i] = rng_(2) + 254;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < kMaxMaskSize ; ++i)
|
||||||
|
mask_[i] = rng_(2) + VPX_BLEND_A64_MAX_ALPHA - 1;
|
||||||
|
|
||||||
|
Common();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void blend_a64_hmask_ref(
|
||||||
|
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) {
|
||||||
|
uint8_t mask2d[BlendA64Mask1DTest8B::kMaxMaskSize]
|
||||||
|
[BlendA64Mask1DTest8B::kMaxMaskSize];
|
||||||
|
|
||||||
|
for (int row = 0 ; row < h ; ++row)
|
||||||
|
for (int col = 0 ; col < w ; ++col)
|
||||||
|
mask2d[row][col] = mask[col];
|
||||||
|
|
||||||
|
vpx_blend_a64_mask_c(dst, dst_stride,
|
||||||
|
src0, src0_stride,
|
||||||
|
src1, src1_stride,
|
||||||
|
&mask2d[0][0], BlendA64Mask1DTest8B::kMaxMaskSize,
|
||||||
|
h, w, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void blend_a64_vmask_ref(
|
||||||
|
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) {
|
||||||
|
uint8_t mask2d[BlendA64Mask1DTest8B::kMaxMaskSize]
|
||||||
|
[BlendA64Mask1DTest8B::kMaxMaskSize];
|
||||||
|
|
||||||
|
for (int row = 0 ; row < h ; ++row)
|
||||||
|
for (int col = 0 ; col < w ; ++col)
|
||||||
|
mask2d[row][col] = mask[row];
|
||||||
|
|
||||||
|
vpx_blend_a64_mask_c(dst, dst_stride,
|
||||||
|
src0, src0_stride,
|
||||||
|
src1, src1_stride,
|
||||||
|
&mask2d[0][0], BlendA64Mask1DTest8B::kMaxMaskSize,
|
||||||
|
h, w, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
C, BlendA64Mask1DTest8B,
|
||||||
|
::testing::Values(TestFuncs(blend_a64_hmask_ref, vpx_blend_a64_hmask_c),
|
||||||
|
TestFuncs(blend_a64_vmask_ref, vpx_blend_a64_vmask_c)));
|
||||||
|
|
||||||
|
#if HAVE_SSE4_1
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE4_1, BlendA64Mask1DTest8B,
|
||||||
|
::testing::Values(
|
||||||
|
TestFuncs(blend_a64_hmask_ref, vpx_blend_a64_hmask_sse4_1),
|
||||||
|
TestFuncs(blend_a64_vmask_ref, vpx_blend_a64_vmask_sse4_1)));
|
||||||
|
#endif // HAVE_SSE4_1
|
||||||
|
|
||||||
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// High bit-depth version
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef void (*FHBD)(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 bd);
|
||||||
|
typedef libvpx_test::FuncParam<FHBD> TestFuncsHBD;
|
||||||
|
|
||||||
|
class BlendA64Mask1DTestHBD : public BlendA64Mask1DTest<FHBD, uint16_t> {
|
||||||
|
protected:
|
||||||
|
void Execute(const uint16_t *p_src0, const uint16_t *p_src1) {
|
||||||
|
params_.ref_func(CONVERT_TO_BYTEPTR(dst_ref_ + dst_offset_), dst_stride_,
|
||||||
|
CONVERT_TO_BYTEPTR(p_src0 + src0_offset_), src0_stride_,
|
||||||
|
CONVERT_TO_BYTEPTR(p_src1 + src1_offset_), src1_stride_,
|
||||||
|
mask_, h_, w_, bit_depth_);
|
||||||
|
ASM_REGISTER_STATE_CHECK(params_.tst_func(
|
||||||
|
CONVERT_TO_BYTEPTR(dst_tst_ + dst_offset_), dst_stride_,
|
||||||
|
CONVERT_TO_BYTEPTR(p_src0 + src0_offset_), src0_stride_,
|
||||||
|
CONVERT_TO_BYTEPTR(p_src1 + src1_offset_), src1_stride_,
|
||||||
|
mask_, h_, w_, bit_depth_));
|
||||||
|
}
|
||||||
|
|
||||||
|
int bit_depth_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(BlendA64Mask1DTestHBD, RandomValues) {
|
||||||
|
for (int iter = 0 ; iter < kIterations && !HasFatalFailure(); ++iter) {
|
||||||
|
switch (rng_(3)) {
|
||||||
|
case 0:
|
||||||
|
bit_depth_ = 8;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
bit_depth_ = 10;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bit_depth_ = 12;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int hi = 1 << bit_depth_;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < kBufSize ; ++i) {
|
||||||
|
dst_ref_[i] = rng_(hi);
|
||||||
|
dst_tst_[i] = rng_(hi);
|
||||||
|
src0_[i] = rng_(hi);
|
||||||
|
src1_[i] = rng_(hi);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < kMaxMaskSize ; ++i)
|
||||||
|
mask_[i] = rng_(VPX_BLEND_A64_MAX_ALPHA + 1);
|
||||||
|
|
||||||
|
Common();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(BlendA64Mask1DTestHBD, ExtremeValues) {
|
||||||
|
for (int iter = 0 ; iter < 1000 && !HasFatalFailure(); ++iter) {
|
||||||
|
switch (rng_(3)) {
|
||||||
|
case 0:
|
||||||
|
bit_depth_ = 8;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
bit_depth_ = 10;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bit_depth_ = 12;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int hi = 1 << bit_depth_;
|
||||||
|
const int lo = hi - 2;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < kBufSize ; ++i) {
|
||||||
|
dst_ref_[i] = rng_(hi - lo) + lo;
|
||||||
|
dst_tst_[i] = rng_(hi - lo) + lo;
|
||||||
|
src0_[i] = rng_(hi - lo) + lo;
|
||||||
|
src1_[i] = rng_(hi - lo) + lo;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < kMaxMaskSize ; ++i)
|
||||||
|
mask_[i] = rng_(2) + VPX_BLEND_A64_MAX_ALPHA - 1;
|
||||||
|
|
||||||
|
Common();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void highbd_blend_a64_hmask_ref(
|
||||||
|
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 bd) {
|
||||||
|
uint8_t mask2d[BlendA64Mask1DTestHBD::kMaxMaskSize]
|
||||||
|
[BlendA64Mask1DTestHBD::kMaxMaskSize];
|
||||||
|
|
||||||
|
for (int row = 0 ; row < h ; ++row)
|
||||||
|
for (int col = 0 ; col < w ; ++col)
|
||||||
|
mask2d[row][col] = mask[col];
|
||||||
|
|
||||||
|
vpx_highbd_blend_a64_mask_c(dst, dst_stride,
|
||||||
|
src0, src0_stride,
|
||||||
|
src1, src1_stride,
|
||||||
|
&mask2d[0][0],
|
||||||
|
BlendA64Mask1DTestHBD::kMaxMaskSize,
|
||||||
|
h, w, 0, 0, bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void highbd_blend_a64_vmask_ref(
|
||||||
|
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 bd) {
|
||||||
|
uint8_t mask2d[BlendA64Mask1DTestHBD::kMaxMaskSize]
|
||||||
|
[BlendA64Mask1DTestHBD::kMaxMaskSize];
|
||||||
|
|
||||||
|
for (int row = 0 ; row < h ; ++row)
|
||||||
|
for (int col = 0 ; col < w ; ++col)
|
||||||
|
mask2d[row][col] = mask[row];
|
||||||
|
|
||||||
|
vpx_highbd_blend_a64_mask_c(dst, dst_stride,
|
||||||
|
src0, src0_stride,
|
||||||
|
src1, src1_stride,
|
||||||
|
&mask2d[0][0],
|
||||||
|
BlendA64Mask1DTestHBD::kMaxMaskSize,
|
||||||
|
h, w, 0, 0, bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
C, BlendA64Mask1DTestHBD,
|
||||||
|
::testing::Values(
|
||||||
|
TestFuncsHBD(highbd_blend_a64_hmask_ref, vpx_highbd_blend_a64_hmask_c),
|
||||||
|
TestFuncsHBD(highbd_blend_a64_vmask_ref, vpx_highbd_blend_a64_vmask_c)));
|
||||||
|
|
||||||
|
#if HAVE_SSE4_1
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE4_1, BlendA64Mask1DTestHBD,
|
||||||
|
::testing::Values(
|
||||||
|
TestFuncsHBD(highbd_blend_a64_hmask_ref,
|
||||||
|
vpx_highbd_blend_a64_hmask_sse4_1),
|
||||||
|
TestFuncsHBD(highbd_blend_a64_vmask_ref,
|
||||||
|
vpx_highbd_blend_a64_vmask_sse4_1)));
|
||||||
|
#endif // HAVE_SSE4_1
|
||||||
|
|
||||||
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
} // namespace
|
||||||
288
test/blend_a64_mask_test.cc
Normal file
288
test/blend_a64_mask_test.cc
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
/*
|
||||||
|
* 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 <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
#include "test/register_state_check.h"
|
||||||
|
|
||||||
|
#include "test/function_equivalence_test.h"
|
||||||
|
|
||||||
|
#include "./vpx_config.h"
|
||||||
|
#include "./vpx_dsp_rtcd.h"
|
||||||
|
#include "vpx/vpx_integer.h"
|
||||||
|
|
||||||
|
#include "./vp10_rtcd.h"
|
||||||
|
|
||||||
|
#include "vp10/common/enums.h"
|
||||||
|
|
||||||
|
#include "vpx_dsp/blend.h"
|
||||||
|
|
||||||
|
using libvpx_test::FunctionEquivalenceTest;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template<typename F, typename T>
|
||||||
|
class BlendA64MaskTest : public FunctionEquivalenceTest<F> {
|
||||||
|
protected:
|
||||||
|
static const int kIterations = 10000;
|
||||||
|
static const int kMaxWidth = MAX_SB_SIZE * 5; // * 5 to cover longer strides
|
||||||
|
static const int kMaxHeight = MAX_SB_SIZE;
|
||||||
|
static const int kBufSize = kMaxWidth * kMaxHeight;
|
||||||
|
static const int kMaxMaskWidth = 2 * MAX_SB_SIZE;
|
||||||
|
static const int kMaxMaskSize = kMaxMaskWidth * kMaxMaskWidth;
|
||||||
|
|
||||||
|
virtual ~BlendA64MaskTest() {}
|
||||||
|
|
||||||
|
virtual void Execute(const T *p_src0, const T *p_src1) = 0;
|
||||||
|
|
||||||
|
void Common() {
|
||||||
|
w_ = 1 << this->rng_(MAX_SB_SIZE_LOG2 + 1);
|
||||||
|
h_ = 1 << this->rng_(MAX_SB_SIZE_LOG2 + 1);
|
||||||
|
|
||||||
|
subx_ = this->rng_(2);
|
||||||
|
suby_ = this->rng_(2);
|
||||||
|
|
||||||
|
dst_offset_ = this->rng_(33);
|
||||||
|
dst_stride_ = this->rng_(kMaxWidth + 1 - w_) + w_;
|
||||||
|
|
||||||
|
src0_offset_ = this->rng_(33);
|
||||||
|
src0_stride_ = this->rng_(kMaxWidth + 1 - w_) + w_;
|
||||||
|
|
||||||
|
src1_offset_ = this->rng_(33);
|
||||||
|
src1_stride_ = this->rng_(kMaxWidth + 1 - w_) + w_;
|
||||||
|
|
||||||
|
mask_stride_ = this->rng_(kMaxWidth + 1 - w_ * (subx_ ? 2 : 1)) +
|
||||||
|
w_ * (subx_ ? 2 : 1);
|
||||||
|
|
||||||
|
T *p_src0;
|
||||||
|
T *p_src1;
|
||||||
|
|
||||||
|
switch (this->rng_(3)) {
|
||||||
|
case 0: // Separate sources
|
||||||
|
p_src0 = src0_;
|
||||||
|
p_src1 = src1_;
|
||||||
|
break;
|
||||||
|
case 1: // src0 == dst
|
||||||
|
p_src0 = dst_tst_;
|
||||||
|
src0_stride_ = dst_stride_;
|
||||||
|
src0_offset_ = dst_offset_;
|
||||||
|
p_src1 = src1_;
|
||||||
|
break;
|
||||||
|
case 2: // src1 == dst
|
||||||
|
p_src0 = src0_;
|
||||||
|
p_src1 = dst_tst_;
|
||||||
|
src1_stride_ = dst_stride_;
|
||||||
|
src1_offset_ = dst_offset_;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
FAIL();
|
||||||
|
}
|
||||||
|
|
||||||
|
Execute(p_src0, p_src1);
|
||||||
|
|
||||||
|
for (int r = 0 ; r < h_ ; ++r) {
|
||||||
|
for (int c = 0 ; c < w_ ; ++c) {
|
||||||
|
ASSERT_EQ(dst_ref_[dst_offset_ + r * dst_stride_ + c],
|
||||||
|
dst_tst_[dst_offset_ + r * dst_stride_ + c]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T dst_ref_[kBufSize];
|
||||||
|
T dst_tst_[kBufSize];
|
||||||
|
size_t dst_stride_;
|
||||||
|
size_t dst_offset_;
|
||||||
|
|
||||||
|
T src0_[kBufSize];
|
||||||
|
size_t src0_stride_;
|
||||||
|
size_t src0_offset_;
|
||||||
|
|
||||||
|
T src1_[kBufSize];
|
||||||
|
size_t src1_stride_;
|
||||||
|
size_t src1_offset_;
|
||||||
|
|
||||||
|
uint8_t mask_[kMaxMaskSize];
|
||||||
|
size_t mask_stride_;
|
||||||
|
|
||||||
|
int w_;
|
||||||
|
int h_;
|
||||||
|
|
||||||
|
bool suby_;
|
||||||
|
bool subx_;
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 8 bit version
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef void (*F8B)(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 suby, int subx);
|
||||||
|
typedef libvpx_test::FuncParam<F8B> TestFuncs;
|
||||||
|
|
||||||
|
class BlendA64MaskTest8B : public BlendA64MaskTest<F8B, uint8_t> {
|
||||||
|
protected:
|
||||||
|
void Execute(const uint8_t *p_src0, const uint8_t *p_src1) {
|
||||||
|
params_.ref_func(dst_ref_ + dst_offset_, dst_stride_,
|
||||||
|
p_src0 + src0_offset_, src0_stride_,
|
||||||
|
p_src1 + src1_offset_, src1_stride_,
|
||||||
|
mask_, kMaxMaskWidth, h_, w_, suby_, subx_);
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
params_.tst_func(dst_tst_ + dst_offset_, dst_stride_,
|
||||||
|
p_src0 + src0_offset_, src0_stride_,
|
||||||
|
p_src1 + src1_offset_, src1_stride_,
|
||||||
|
mask_, kMaxMaskWidth, h_, w_, suby_, subx_));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(BlendA64MaskTest8B, RandomValues) {
|
||||||
|
for (int iter = 0 ; iter < kIterations && !HasFatalFailure(); ++iter) {
|
||||||
|
for (int i = 0 ; i < kBufSize ; ++i) {
|
||||||
|
dst_ref_[i] = rng_.Rand8();
|
||||||
|
dst_tst_[i] = rng_.Rand8();
|
||||||
|
|
||||||
|
src0_[i] = rng_.Rand8();
|
||||||
|
src1_[i] = rng_.Rand8();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < kMaxMaskSize ; ++i)
|
||||||
|
mask_[i] = rng_(VPX_BLEND_A64_MAX_ALPHA + 1);
|
||||||
|
|
||||||
|
Common();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(BlendA64MaskTest8B, ExtremeValues) {
|
||||||
|
for (int iter = 0 ; iter < kIterations && !HasFatalFailure(); ++iter) {
|
||||||
|
for (int i = 0 ; i < kBufSize ; ++i) {
|
||||||
|
dst_ref_[i] = rng_(2) + 254;
|
||||||
|
dst_tst_[i] = rng_(2) + 254;
|
||||||
|
src0_[i] = rng_(2) + 254;
|
||||||
|
src1_[i] = rng_(2) + 254;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < kMaxMaskSize ; ++i)
|
||||||
|
mask_[i] = rng_(2) + VPX_BLEND_A64_MAX_ALPHA - 1;
|
||||||
|
|
||||||
|
Common();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_SSE4_1
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE4_1_C_COMPARE, BlendA64MaskTest8B,
|
||||||
|
::testing::Values(
|
||||||
|
TestFuncs(vpx_blend_a64_mask_c, vpx_blend_a64_mask_sse4_1)));
|
||||||
|
#endif // HAVE_SSE4_1
|
||||||
|
|
||||||
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// High bit-depth version
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef void (*FHBD)(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 suby, int subx, int bd);
|
||||||
|
typedef libvpx_test::FuncParam<FHBD> TestFuncsHBD;
|
||||||
|
|
||||||
|
class BlendA64MaskTestHBD : public BlendA64MaskTest<FHBD, uint16_t> {
|
||||||
|
protected:
|
||||||
|
void Execute(const uint16_t *p_src0, const uint16_t *p_src1) {
|
||||||
|
params_.ref_func(CONVERT_TO_BYTEPTR(dst_ref_ + dst_offset_), dst_stride_,
|
||||||
|
CONVERT_TO_BYTEPTR(p_src0 + src0_offset_), src0_stride_,
|
||||||
|
CONVERT_TO_BYTEPTR(p_src1 + src1_offset_), src1_stride_,
|
||||||
|
mask_, kMaxMaskWidth, h_, w_, suby_, subx_, bit_depth_);
|
||||||
|
ASM_REGISTER_STATE_CHECK(params_.tst_func(
|
||||||
|
CONVERT_TO_BYTEPTR(dst_tst_ + dst_offset_), dst_stride_,
|
||||||
|
CONVERT_TO_BYTEPTR(p_src0 + src0_offset_), src0_stride_,
|
||||||
|
CONVERT_TO_BYTEPTR(p_src1 + src1_offset_), src1_stride_,
|
||||||
|
mask_, kMaxMaskWidth, h_, w_, suby_, subx_, bit_depth_));
|
||||||
|
}
|
||||||
|
|
||||||
|
int bit_depth_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(BlendA64MaskTestHBD, RandomValues) {
|
||||||
|
for (int iter = 0 ; iter < kIterations && !HasFatalFailure(); ++iter) {
|
||||||
|
switch (rng_(3)) {
|
||||||
|
case 0:
|
||||||
|
bit_depth_ = 8;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
bit_depth_ = 10;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bit_depth_ = 12;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int hi = 1 << bit_depth_;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < kBufSize ; ++i) {
|
||||||
|
dst_ref_[i] = rng_(hi);
|
||||||
|
dst_tst_[i] = rng_(hi);
|
||||||
|
src0_[i] = rng_(hi);
|
||||||
|
src1_[i] = rng_(hi);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < kMaxMaskSize ; ++i)
|
||||||
|
mask_[i] = rng_(VPX_BLEND_A64_MAX_ALPHA + 1);
|
||||||
|
|
||||||
|
Common();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(BlendA64MaskTestHBD, ExtremeValues) {
|
||||||
|
for (int iter = 0 ; iter < 1000 && !HasFatalFailure(); ++iter) {
|
||||||
|
switch (rng_(3)) {
|
||||||
|
case 0:
|
||||||
|
bit_depth_ = 8;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
bit_depth_ = 10;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bit_depth_ = 12;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int hi = 1 << bit_depth_;
|
||||||
|
const int lo = hi - 2;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < kBufSize ; ++i) {
|
||||||
|
dst_ref_[i] = rng_(hi - lo) + lo;
|
||||||
|
dst_tst_[i] = rng_(hi - lo) + lo;
|
||||||
|
src0_[i] = rng_(hi - lo) + lo;
|
||||||
|
src1_[i] = rng_(hi - lo) + lo;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < kMaxMaskSize ; ++i)
|
||||||
|
mask_[i] = rng_(2) + VPX_BLEND_A64_MAX_ALPHA - 1;
|
||||||
|
|
||||||
|
Common();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_SSE4_1
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE4_1_C_COMPARE, BlendA64MaskTestHBD,
|
||||||
|
::testing::Values(
|
||||||
|
TestFuncsHBD(vpx_highbd_blend_a64_mask_c,
|
||||||
|
vpx_highbd_blend_a64_mask_sse4_1)));
|
||||||
|
#endif // HAVE_SSE4_1
|
||||||
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
} // namespace
|
||||||
@@ -1,223 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#if CONFIG_VP9_ENCODER
|
|
||||||
#include "./vp9_rtcd.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "test/acm_random.h"
|
|
||||||
#include "test/clear_system_state.h"
|
|
||||||
#include "test/register_state_check.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
|
|
||||||
#include "vpx_mem/vpx_mem.h"
|
|
||||||
|
|
||||||
extern "C" double vp9_get_blockiness(const unsigned char *img1, int img1_pitch,
|
|
||||||
const unsigned char *img2, int img2_pitch,
|
|
||||||
int width, int height);
|
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
class BlockinessTestBase : public ::testing::Test {
|
|
||||||
public:
|
|
||||||
BlockinessTestBase(int width, int height) : width_(width), height_(height) {}
|
|
||||||
|
|
||||||
static void SetUpTestCase() {
|
|
||||||
source_data_ = reinterpret_cast<uint8_t *>(
|
|
||||||
vpx_memalign(kDataAlignment, kDataBufferSize));
|
|
||||||
reference_data_ = reinterpret_cast<uint8_t *>(
|
|
||||||
vpx_memalign(kDataAlignment, kDataBufferSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void TearDownTestCase() {
|
|
||||||
vpx_free(source_data_);
|
|
||||||
source_data_ = NULL;
|
|
||||||
vpx_free(reference_data_);
|
|
||||||
reference_data_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Handle frames up to 640x480
|
|
||||||
static const int kDataAlignment = 16;
|
|
||||||
static const int kDataBufferSize = 640 * 480;
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
|
||||||
source_stride_ = (width_ + 31) & ~31;
|
|
||||||
reference_stride_ = width_ * 2;
|
|
||||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
|
||||||
}
|
|
||||||
|
|
||||||
void FillConstant(uint8_t *data, int stride, uint8_t fill_constant, int width,
|
|
||||||
int height) {
|
|
||||||
for (int h = 0; h < height; ++h) {
|
|
||||||
for (int w = 0; w < width; ++w) {
|
|
||||||
data[h * stride + w] = fill_constant;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FillConstant(uint8_t *data, int stride, uint8_t fill_constant) {
|
|
||||||
FillConstant(data, stride, fill_constant, width_, height_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FillRandom(uint8_t *data, int stride, int width, int height) {
|
|
||||||
for (int h = 0; h < height; ++h) {
|
|
||||||
for (int w = 0; w < width; ++w) {
|
|
||||||
data[h * stride + w] = rnd_.Rand8();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FillRandom(uint8_t *data, int stride) {
|
|
||||||
FillRandom(data, stride, width_, height_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FillRandomBlocky(uint8_t *data, int stride) {
|
|
||||||
for (int h = 0; h < height_; h += 4) {
|
|
||||||
for (int w = 0; w < width_; w += 4) {
|
|
||||||
FillRandom(data + h * stride + w, stride, 4, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FillCheckerboard(uint8_t *data, int stride) {
|
|
||||||
for (int h = 0; h < height_; h += 4) {
|
|
||||||
for (int w = 0; w < width_; w += 4) {
|
|
||||||
if (((h / 4) ^ (w / 4)) & 1) {
|
|
||||||
FillConstant(data + h * stride + w, stride, 255, 4, 4);
|
|
||||||
} else {
|
|
||||||
FillConstant(data + h * stride + w, stride, 0, 4, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Blur(uint8_t *data, int stride, int taps) {
|
|
||||||
int sum = 0;
|
|
||||||
int half_taps = taps / 2;
|
|
||||||
for (int h = 0; h < height_; ++h) {
|
|
||||||
for (int w = 0; w < taps; ++w) {
|
|
||||||
sum += data[w + h * stride];
|
|
||||||
}
|
|
||||||
for (int w = taps; w < width_; ++w) {
|
|
||||||
sum += data[w + h * stride] - data[w - taps + h * stride];
|
|
||||||
data[w - half_taps + h * stride] = (sum + half_taps) / taps;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int w = 0; w < width_; ++w) {
|
|
||||||
for (int h = 0; h < taps; ++h) {
|
|
||||||
sum += data[h + w * stride];
|
|
||||||
}
|
|
||||||
for (int h = taps; h < height_; ++h) {
|
|
||||||
sum += data[w + h * stride] - data[(h - taps) * stride + w];
|
|
||||||
data[(h - half_taps) * stride + w] = (sum + half_taps) / taps;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int width_, height_;
|
|
||||||
static uint8_t *source_data_;
|
|
||||||
int source_stride_;
|
|
||||||
static uint8_t *reference_data_;
|
|
||||||
int reference_stride_;
|
|
||||||
|
|
||||||
ACMRandom rnd_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if CONFIG_VP9_ENCODER
|
|
||||||
typedef std::tr1::tuple<int, int> BlockinessParam;
|
|
||||||
class BlockinessVP9Test
|
|
||||||
: public BlockinessTestBase,
|
|
||||||
public ::testing::WithParamInterface<BlockinessParam> {
|
|
||||||
public:
|
|
||||||
BlockinessVP9Test() : BlockinessTestBase(GET_PARAM(0), GET_PARAM(1)) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
double GetBlockiness() const {
|
|
||||||
return vp9_get_blockiness(source_data_, source_stride_, reference_data_,
|
|
||||||
reference_stride_, width_, height_);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif // CONFIG_VP9_ENCODER
|
|
||||||
|
|
||||||
uint8_t *BlockinessTestBase::source_data_ = NULL;
|
|
||||||
uint8_t *BlockinessTestBase::reference_data_ = NULL;
|
|
||||||
|
|
||||||
#if CONFIG_VP9_ENCODER
|
|
||||||
TEST_P(BlockinessVP9Test, SourceBlockierThanReference) {
|
|
||||||
// Source is blockier than reference.
|
|
||||||
FillRandomBlocky(source_data_, source_stride_);
|
|
||||||
FillConstant(reference_data_, reference_stride_, 128);
|
|
||||||
const double super_blocky = GetBlockiness();
|
|
||||||
|
|
||||||
EXPECT_DOUBLE_EQ(0.0, super_blocky)
|
|
||||||
<< "Blocky source should produce 0 blockiness.";
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(BlockinessVP9Test, ReferenceBlockierThanSource) {
|
|
||||||
// Source is blockier than reference.
|
|
||||||
FillConstant(source_data_, source_stride_, 128);
|
|
||||||
FillRandomBlocky(reference_data_, reference_stride_);
|
|
||||||
const double super_blocky = GetBlockiness();
|
|
||||||
|
|
||||||
EXPECT_GT(super_blocky, 0.0)
|
|
||||||
<< "Blocky reference should score high for blockiness.";
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(BlockinessVP9Test, BlurringDecreasesBlockiness) {
|
|
||||||
// Source is blockier than reference.
|
|
||||||
FillConstant(source_data_, source_stride_, 128);
|
|
||||||
FillRandomBlocky(reference_data_, reference_stride_);
|
|
||||||
const double super_blocky = GetBlockiness();
|
|
||||||
|
|
||||||
Blur(reference_data_, reference_stride_, 4);
|
|
||||||
const double less_blocky = GetBlockiness();
|
|
||||||
|
|
||||||
EXPECT_GT(super_blocky, less_blocky)
|
|
||||||
<< "A straight blur should decrease blockiness.";
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(BlockinessVP9Test, WorstCaseBlockiness) {
|
|
||||||
// Source is blockier than reference.
|
|
||||||
FillConstant(source_data_, source_stride_, 128);
|
|
||||||
FillCheckerboard(reference_data_, reference_stride_);
|
|
||||||
|
|
||||||
const double super_blocky = GetBlockiness();
|
|
||||||
|
|
||||||
Blur(reference_data_, reference_stride_, 4);
|
|
||||||
const double less_blocky = GetBlockiness();
|
|
||||||
|
|
||||||
EXPECT_GT(super_blocky, less_blocky)
|
|
||||||
<< "A straight blur should decrease blockiness.";
|
|
||||||
}
|
|
||||||
#endif // CONFIG_VP9_ENCODER
|
|
||||||
|
|
||||||
using std::tr1::make_tuple;
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// C functions
|
|
||||||
|
|
||||||
#if CONFIG_VP9_ENCODER
|
|
||||||
const BlockinessParam c_vp9_tests[] = {
|
|
||||||
make_tuple(320, 240), make_tuple(318, 242), make_tuple(318, 238),
|
|
||||||
};
|
|
||||||
INSTANTIATE_TEST_CASE_P(C, BlockinessVP9Test, ::testing::ValuesIn(c_vp9_tests));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
@@ -34,7 +34,6 @@ TEST(VP9, TestBitIO) {
|
|||||||
|
|
||||||
for (int i = 0; i < kBitsToTest; ++i) {
|
for (int i = 0; i < kBitsToTest; ++i) {
|
||||||
const int parity = i & 1;
|
const int parity = i & 1;
|
||||||
/* clang-format off */
|
|
||||||
probas[i] =
|
probas[i] =
|
||||||
(method == 0) ? 0 : (method == 1) ? 255 :
|
(method == 0) ? 0 : (method == 1) ? 255 :
|
||||||
(method == 2) ? 128 :
|
(method == 2) ? 128 :
|
||||||
@@ -45,7 +44,6 @@ TEST(VP9, TestBitIO) {
|
|||||||
(method == 6) ?
|
(method == 6) ?
|
||||||
(parity ? rnd(64) : 255 - rnd(64)) :
|
(parity ? rnd(64) : 255 - rnd(64)) :
|
||||||
(parity ? rnd(32) : 255 - rnd(32));
|
(parity ? rnd(32) : 255 - rnd(32));
|
||||||
/* clang-format on */
|
|
||||||
}
|
}
|
||||||
for (int bit_method = 0; bit_method <= 3; ++bit_method) {
|
for (int bit_method = 0; bit_method <= 3; ++bit_method) {
|
||||||
const int random_seed = 6432;
|
const int random_seed = 6432;
|
||||||
@@ -81,7 +79,8 @@ TEST(VP9, TestBitIO) {
|
|||||||
}
|
}
|
||||||
GTEST_ASSERT_EQ(vpx_read(&br, probas[i]), bit)
|
GTEST_ASSERT_EQ(vpx_read(&br, probas[i]), bit)
|
||||||
<< "pos: " << i << " / " << kBitsToTest
|
<< "pos: " << i << " / " << kBitsToTest
|
||||||
<< " bit_method: " << bit_method << " method: " << method;
|
<< " bit_method: " << bit_method
|
||||||
|
<< " method: " << method;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17,8 +17,7 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class BordersTest
|
class BordersTest : public ::libvpx_test::EncoderTest,
|
||||||
: public ::libvpx_test::EncoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||||
protected:
|
protected:
|
||||||
BordersTest() : EncoderTest(GET_PARAM(0)) {}
|
BordersTest() : EncoderTest(GET_PARAM(0)) {}
|
||||||
@@ -79,6 +78,6 @@ TEST_P(BordersTest, TestLowBitrate) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
}
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(BordersTest,
|
VP10_INSTANTIATE_TEST_CASE(BordersTest, ::testing::Values(
|
||||||
::testing::Values(::libvpx_test::kTwoPassGood));
|
::libvpx_test::kTwoPassGood));
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
382
test/buffer.h
382
test/buffer.h
@@ -1,382 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef TEST_BUFFER_H_
|
|
||||||
#define TEST_BUFFER_H_
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "test/acm_random.h"
|
|
||||||
#include "vpx/vpx_integer.h"
|
|
||||||
#include "vpx_mem/vpx_mem.h"
|
|
||||||
|
|
||||||
namespace libvpx_test {
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class Buffer {
|
|
||||||
public:
|
|
||||||
Buffer(int width, int height, int top_padding, int left_padding,
|
|
||||||
int right_padding, int bottom_padding)
|
|
||||||
: width_(width), height_(height), top_padding_(top_padding),
|
|
||||||
left_padding_(left_padding), right_padding_(right_padding),
|
|
||||||
bottom_padding_(bottom_padding), alignment_(0), padding_value_(0),
|
|
||||||
stride_(0), raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}
|
|
||||||
|
|
||||||
Buffer(int width, int height, int top_padding, int left_padding,
|
|
||||||
int right_padding, int bottom_padding, unsigned int alignment)
|
|
||||||
: width_(width), height_(height), top_padding_(top_padding),
|
|
||||||
left_padding_(left_padding), right_padding_(right_padding),
|
|
||||||
bottom_padding_(bottom_padding), alignment_(alignment),
|
|
||||||
padding_value_(0), stride_(0), raw_size_(0), num_elements_(0),
|
|
||||||
raw_buffer_(NULL) {}
|
|
||||||
|
|
||||||
Buffer(int width, int height, int padding)
|
|
||||||
: width_(width), height_(height), top_padding_(padding),
|
|
||||||
left_padding_(padding), right_padding_(padding),
|
|
||||||
bottom_padding_(padding), alignment_(0), padding_value_(0), stride_(0),
|
|
||||||
raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}
|
|
||||||
|
|
||||||
Buffer(int width, int height, int padding, unsigned int alignment)
|
|
||||||
: width_(width), height_(height), top_padding_(padding),
|
|
||||||
left_padding_(padding), right_padding_(padding),
|
|
||||||
bottom_padding_(padding), alignment_(alignment), padding_value_(0),
|
|
||||||
stride_(0), raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}
|
|
||||||
|
|
||||||
~Buffer() {
|
|
||||||
if (alignment_) {
|
|
||||||
vpx_free(raw_buffer_);
|
|
||||||
} else {
|
|
||||||
delete[] raw_buffer_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
T *TopLeftPixel() const;
|
|
||||||
|
|
||||||
int stride() const { return stride_; }
|
|
||||||
|
|
||||||
// Set the buffer (excluding padding) to 'value'.
|
|
||||||
void Set(const T value);
|
|
||||||
|
|
||||||
// Set the buffer (excluding padding) to the output of ACMRandom function
|
|
||||||
// 'rand_func'.
|
|
||||||
void Set(ACMRandom *rand_class, T (ACMRandom::*rand_func)());
|
|
||||||
|
|
||||||
// Set the buffer (excluding padding) to the output of ACMRandom function
|
|
||||||
// 'RandRange' with range 'low' to 'high' which typically must be within
|
|
||||||
// testing::internal::Random::kMaxRange (1u << 31). However, because we want
|
|
||||||
// to allow negative low (and high) values, it is restricted to INT32_MAX
|
|
||||||
// here.
|
|
||||||
void Set(ACMRandom *rand_class, const T low, const T high);
|
|
||||||
|
|
||||||
// Copy the contents of Buffer 'a' (excluding padding).
|
|
||||||
void CopyFrom(const Buffer<T> &a);
|
|
||||||
|
|
||||||
void DumpBuffer() const;
|
|
||||||
|
|
||||||
// Highlight the differences between two buffers if they are the same size.
|
|
||||||
void PrintDifference(const Buffer<T> &a) const;
|
|
||||||
|
|
||||||
bool HasPadding() const;
|
|
||||||
|
|
||||||
// Sets all the values in the buffer to 'padding_value'.
|
|
||||||
void SetPadding(const T padding_value);
|
|
||||||
|
|
||||||
// Checks if all the values (excluding padding) are equal to 'value' if the
|
|
||||||
// Buffers are the same size.
|
|
||||||
bool CheckValues(const T value) const;
|
|
||||||
|
|
||||||
// Check that padding matches the expected value or there is no padding.
|
|
||||||
bool CheckPadding() const;
|
|
||||||
|
|
||||||
// Compare the non-padding portion of two buffers if they are the same size.
|
|
||||||
bool CheckValues(const Buffer<T> &a) const;
|
|
||||||
|
|
||||||
bool Init() {
|
|
||||||
if (raw_buffer_ != NULL) return false;
|
|
||||||
EXPECT_GT(width_, 0);
|
|
||||||
EXPECT_GT(height_, 0);
|
|
||||||
EXPECT_GE(top_padding_, 0);
|
|
||||||
EXPECT_GE(left_padding_, 0);
|
|
||||||
EXPECT_GE(right_padding_, 0);
|
|
||||||
EXPECT_GE(bottom_padding_, 0);
|
|
||||||
stride_ = left_padding_ + width_ + right_padding_;
|
|
||||||
num_elements_ = stride_ * (top_padding_ + height_ + bottom_padding_);
|
|
||||||
raw_size_ = num_elements_ * sizeof(T);
|
|
||||||
if (alignment_) {
|
|
||||||
EXPECT_GE(alignment_, sizeof(T));
|
|
||||||
// Ensure alignment of the first value will be preserved.
|
|
||||||
EXPECT_EQ((left_padding_ * sizeof(T)) % alignment_, 0u);
|
|
||||||
// Ensure alignment of the subsequent rows will be preserved when there is
|
|
||||||
// a stride.
|
|
||||||
if (stride_ != width_) {
|
|
||||||
EXPECT_EQ((stride_ * sizeof(T)) % alignment_, 0u);
|
|
||||||
}
|
|
||||||
raw_buffer_ = reinterpret_cast<T *>(vpx_memalign(alignment_, raw_size_));
|
|
||||||
} else {
|
|
||||||
raw_buffer_ = new (std::nothrow) T[num_elements_];
|
|
||||||
}
|
|
||||||
EXPECT_TRUE(raw_buffer_ != NULL);
|
|
||||||
SetPadding(std::numeric_limits<T>::max());
|
|
||||||
return !::testing::Test::HasFailure();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool BufferSizesMatch(const Buffer<T> &a) const;
|
|
||||||
|
|
||||||
const int width_;
|
|
||||||
const int height_;
|
|
||||||
const int top_padding_;
|
|
||||||
const int left_padding_;
|
|
||||||
const int right_padding_;
|
|
||||||
const int bottom_padding_;
|
|
||||||
const unsigned int alignment_;
|
|
||||||
T padding_value_;
|
|
||||||
int stride_;
|
|
||||||
int raw_size_;
|
|
||||||
int num_elements_;
|
|
||||||
T *raw_buffer_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T *Buffer<T>::TopLeftPixel() const {
|
|
||||||
if (!raw_buffer_) return NULL;
|
|
||||||
return raw_buffer_ + (top_padding_ * stride_) + left_padding_;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Buffer<T>::Set(const T value) {
|
|
||||||
if (!raw_buffer_) return;
|
|
||||||
T *src = TopLeftPixel();
|
|
||||||
for (int height = 0; height < height_; ++height) {
|
|
||||||
for (int width = 0; width < width_; ++width) {
|
|
||||||
src[width] = value;
|
|
||||||
}
|
|
||||||
src += stride_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Buffer<T>::Set(ACMRandom *rand_class, T (ACMRandom::*rand_func)()) {
|
|
||||||
if (!raw_buffer_) return;
|
|
||||||
T *src = TopLeftPixel();
|
|
||||||
for (int height = 0; height < height_; ++height) {
|
|
||||||
for (int width = 0; width < width_; ++width) {
|
|
||||||
src[width] = (*rand_class.*rand_func)();
|
|
||||||
}
|
|
||||||
src += stride_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Buffer<T>::Set(ACMRandom *rand_class, const T low, const T high) {
|
|
||||||
if (!raw_buffer_) return;
|
|
||||||
|
|
||||||
EXPECT_LE(low, high);
|
|
||||||
EXPECT_LE(static_cast<int64_t>(high) - low,
|
|
||||||
std::numeric_limits<int32_t>::max());
|
|
||||||
|
|
||||||
T *src = TopLeftPixel();
|
|
||||||
for (int height = 0; height < height_; ++height) {
|
|
||||||
for (int width = 0; width < width_; ++width) {
|
|
||||||
// 'low' will be promoted to unsigned given the return type of RandRange.
|
|
||||||
// Store the value as an int to avoid unsigned overflow warnings when
|
|
||||||
// 'low' is negative.
|
|
||||||
const int32_t value =
|
|
||||||
static_cast<int32_t>((*rand_class).RandRange(high - low));
|
|
||||||
src[width] = static_cast<T>(value + low);
|
|
||||||
}
|
|
||||||
src += stride_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Buffer<T>::CopyFrom(const Buffer<T> &a) {
|
|
||||||
if (!raw_buffer_) return;
|
|
||||||
if (!BufferSizesMatch(a)) return;
|
|
||||||
|
|
||||||
T *a_src = a.TopLeftPixel();
|
|
||||||
T *b_src = this->TopLeftPixel();
|
|
||||||
for (int height = 0; height < height_; ++height) {
|
|
||||||
for (int width = 0; width < width_; ++width) {
|
|
||||||
b_src[width] = a_src[width];
|
|
||||||
}
|
|
||||||
a_src += a.stride();
|
|
||||||
b_src += this->stride();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Buffer<T>::DumpBuffer() const {
|
|
||||||
if (!raw_buffer_) return;
|
|
||||||
for (int height = 0; height < height_ + top_padding_ + bottom_padding_;
|
|
||||||
++height) {
|
|
||||||
for (int width = 0; width < stride_; ++width) {
|
|
||||||
printf("%4d", raw_buffer_[height + width * stride_]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool Buffer<T>::HasPadding() const {
|
|
||||||
if (!raw_buffer_) return false;
|
|
||||||
return top_padding_ || left_padding_ || right_padding_ || bottom_padding_;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Buffer<T>::PrintDifference(const Buffer<T> &a) const {
|
|
||||||
if (!raw_buffer_) return;
|
|
||||||
if (!BufferSizesMatch(a)) return;
|
|
||||||
|
|
||||||
T *a_src = a.TopLeftPixel();
|
|
||||||
T *b_src = TopLeftPixel();
|
|
||||||
|
|
||||||
printf("This buffer:\n");
|
|
||||||
for (int height = 0; height < height_; ++height) {
|
|
||||||
for (int width = 0; width < width_; ++width) {
|
|
||||||
if (a_src[width] != b_src[width]) {
|
|
||||||
printf("*%3d", b_src[width]);
|
|
||||||
} else {
|
|
||||||
printf("%4d", b_src[width]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
a_src += a.stride();
|
|
||||||
b_src += this->stride();
|
|
||||||
}
|
|
||||||
|
|
||||||
a_src = a.TopLeftPixel();
|
|
||||||
b_src = TopLeftPixel();
|
|
||||||
|
|
||||||
printf("Reference buffer:\n");
|
|
||||||
for (int height = 0; height < height_; ++height) {
|
|
||||||
for (int width = 0; width < width_; ++width) {
|
|
||||||
if (a_src[width] != b_src[width]) {
|
|
||||||
printf("*%3d", a_src[width]);
|
|
||||||
} else {
|
|
||||||
printf("%4d", a_src[width]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
a_src += a.stride();
|
|
||||||
b_src += this->stride();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Buffer<T>::SetPadding(const T padding_value) {
|
|
||||||
if (!raw_buffer_) return;
|
|
||||||
padding_value_ = padding_value;
|
|
||||||
|
|
||||||
T *src = raw_buffer_;
|
|
||||||
for (int i = 0; i < num_elements_; ++i) {
|
|
||||||
src[i] = padding_value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool Buffer<T>::CheckValues(const T value) const {
|
|
||||||
if (!raw_buffer_) return false;
|
|
||||||
T *src = TopLeftPixel();
|
|
||||||
for (int height = 0; height < height_; ++height) {
|
|
||||||
for (int width = 0; width < width_; ++width) {
|
|
||||||
if (value != src[width]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
src += stride_;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool Buffer<T>::CheckPadding() const {
|
|
||||||
if (!raw_buffer_) return false;
|
|
||||||
if (!HasPadding()) return true;
|
|
||||||
|
|
||||||
// Top padding.
|
|
||||||
T const *top = raw_buffer_;
|
|
||||||
for (int i = 0; i < stride_ * top_padding_; ++i) {
|
|
||||||
if (padding_value_ != top[i]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Left padding.
|
|
||||||
T const *left = TopLeftPixel() - left_padding_;
|
|
||||||
for (int height = 0; height < height_; ++height) {
|
|
||||||
for (int width = 0; width < left_padding_; ++width) {
|
|
||||||
if (padding_value_ != left[width]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
left += stride_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Right padding.
|
|
||||||
T const *right = TopLeftPixel() + width_;
|
|
||||||
for (int height = 0; height < height_; ++height) {
|
|
||||||
for (int width = 0; width < right_padding_; ++width) {
|
|
||||||
if (padding_value_ != right[width]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
right += stride_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bottom padding
|
|
||||||
T const *bottom = raw_buffer_ + (top_padding_ + height_) * stride_;
|
|
||||||
for (int i = 0; i < stride_ * bottom_padding_; ++i) {
|
|
||||||
if (padding_value_ != bottom[i]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool Buffer<T>::CheckValues(const Buffer<T> &a) const {
|
|
||||||
if (!raw_buffer_) return false;
|
|
||||||
if (!BufferSizesMatch(a)) return false;
|
|
||||||
|
|
||||||
T *a_src = a.TopLeftPixel();
|
|
||||||
T *b_src = this->TopLeftPixel();
|
|
||||||
for (int height = 0; height < height_; ++height) {
|
|
||||||
for (int width = 0; width < width_; ++width) {
|
|
||||||
if (a_src[width] != b_src[width]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a_src += a.stride();
|
|
||||||
b_src += this->stride();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool Buffer<T>::BufferSizesMatch(const Buffer<T> &a) const {
|
|
||||||
if (!raw_buffer_) return false;
|
|
||||||
if (a.width_ != this->width_ || a.height_ != this->height_) {
|
|
||||||
printf(
|
|
||||||
"Reference buffer of size %dx%d does not match this buffer which is "
|
|
||||||
"size %dx%d\n",
|
|
||||||
a.width_, a.height_, this->width_, this->height_);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} // namespace libvpx_test
|
|
||||||
#endif // TEST_BUFFER_H_
|
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "test/codec_factory.h"
|
|
||||||
#include "test/decode_test_driver.h"
|
|
||||||
#include "test/md5_helper.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
#if CONFIG_WEBM_IO
|
|
||||||
#include "test/webm_video_source.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
#if CONFIG_WEBM_IO
|
|
||||||
|
|
||||||
const int kLegacyByteAlignment = 0;
|
|
||||||
const int kLegacyYPlaneByteAlignment = 32;
|
|
||||||
const int kNumPlanesToCheck = 3;
|
|
||||||
const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm";
|
|
||||||
const char kVP9Md5File[] = "vp90-2-02-size-lf-1920x1080.webm.md5";
|
|
||||||
|
|
||||||
struct ByteAlignmentTestParam {
|
|
||||||
int byte_alignment;
|
|
||||||
vpx_codec_err_t expected_value;
|
|
||||||
bool decode_remaining;
|
|
||||||
};
|
|
||||||
|
|
||||||
const ByteAlignmentTestParam kBaTestParams[] = {
|
|
||||||
{ kLegacyByteAlignment, VPX_CODEC_OK, true },
|
|
||||||
{ 32, VPX_CODEC_OK, true },
|
|
||||||
{ 64, VPX_CODEC_OK, true },
|
|
||||||
{ 128, VPX_CODEC_OK, true },
|
|
||||||
{ 256, VPX_CODEC_OK, true },
|
|
||||||
{ 512, VPX_CODEC_OK, true },
|
|
||||||
{ 1024, VPX_CODEC_OK, true },
|
|
||||||
{ 1, VPX_CODEC_INVALID_PARAM, false },
|
|
||||||
{ -2, VPX_CODEC_INVALID_PARAM, false },
|
|
||||||
{ 4, VPX_CODEC_INVALID_PARAM, false },
|
|
||||||
{ 16, VPX_CODEC_INVALID_PARAM, false },
|
|
||||||
{ 255, VPX_CODEC_INVALID_PARAM, false },
|
|
||||||
{ 2048, VPX_CODEC_INVALID_PARAM, false },
|
|
||||||
};
|
|
||||||
|
|
||||||
// Class for testing byte alignment of reference buffers.
|
|
||||||
class ByteAlignmentTest
|
|
||||||
: public ::testing::TestWithParam<ByteAlignmentTestParam> {
|
|
||||||
protected:
|
|
||||||
ByteAlignmentTest() : video_(NULL), decoder_(NULL), md5_file_(NULL) {}
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
|
||||||
video_ = new libvpx_test::WebMVideoSource(kVP9TestFile);
|
|
||||||
ASSERT_TRUE(video_ != NULL);
|
|
||||||
video_->Init();
|
|
||||||
video_->Begin();
|
|
||||||
|
|
||||||
const vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
|
||||||
decoder_ = new libvpx_test::VP9Decoder(cfg, 0);
|
|
||||||
ASSERT_TRUE(decoder_ != NULL);
|
|
||||||
|
|
||||||
OpenMd5File(kVP9Md5File);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void TearDown() {
|
|
||||||
if (md5_file_ != NULL) fclose(md5_file_);
|
|
||||||
|
|
||||||
delete decoder_;
|
|
||||||
delete video_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetByteAlignment(int byte_alignment, vpx_codec_err_t expected_value) {
|
|
||||||
decoder_->Control(VP9_SET_BYTE_ALIGNMENT, byte_alignment, expected_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
vpx_codec_err_t DecodeOneFrame(int byte_alignment_to_check) {
|
|
||||||
const vpx_codec_err_t res =
|
|
||||||
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
|
|
||||||
CheckDecodedFrames(byte_alignment_to_check);
|
|
||||||
if (res == VPX_CODEC_OK) video_->Next();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
vpx_codec_err_t DecodeRemainingFrames(int byte_alignment_to_check) {
|
|
||||||
for (; video_->cxdata() != NULL; video_->Next()) {
|
|
||||||
const vpx_codec_err_t res =
|
|
||||||
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
|
|
||||||
if (res != VPX_CODEC_OK) return res;
|
|
||||||
CheckDecodedFrames(byte_alignment_to_check);
|
|
||||||
}
|
|
||||||
return VPX_CODEC_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Check if |data| is aligned to |byte_alignment_to_check|.
|
|
||||||
// |byte_alignment_to_check| must be a power of 2.
|
|
||||||
void CheckByteAlignment(const uint8_t *data, int byte_alignment_to_check) {
|
|
||||||
ASSERT_EQ(0u, reinterpret_cast<size_t>(data) % byte_alignment_to_check);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterate through the planes of the decoded frames and check for
|
|
||||||
// alignment based off |byte_alignment_to_check|.
|
|
||||||
void CheckDecodedFrames(int byte_alignment_to_check) {
|
|
||||||
libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData();
|
|
||||||
const vpx_image_t *img;
|
|
||||||
|
|
||||||
// Get decompressed data
|
|
||||||
while ((img = dec_iter.Next()) != NULL) {
|
|
||||||
if (byte_alignment_to_check == kLegacyByteAlignment) {
|
|
||||||
CheckByteAlignment(img->planes[0], kLegacyYPlaneByteAlignment);
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < kNumPlanesToCheck; ++i) {
|
|
||||||
CheckByteAlignment(img->planes[i], byte_alignment_to_check);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CheckMd5(*img);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(fgalligan): Move the MD5 testing code into another class.
|
|
||||||
void OpenMd5File(const std::string &md5_file_name_) {
|
|
||||||
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
|
|
||||||
ASSERT_TRUE(md5_file_ != NULL)
|
|
||||||
<< "MD5 file open failed. Filename: " << md5_file_name_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckMd5(const vpx_image_t &img) {
|
|
||||||
ASSERT_TRUE(md5_file_ != NULL);
|
|
||||||
char expected_md5[33];
|
|
||||||
char junk[128];
|
|
||||||
|
|
||||||
// Read correct md5 checksums.
|
|
||||||
const int res = fscanf(md5_file_, "%s %s", expected_md5, junk);
|
|
||||||
ASSERT_NE(EOF, res) << "Read md5 data failed";
|
|
||||||
expected_md5[32] = '\0';
|
|
||||||
|
|
||||||
::libvpx_test::MD5 md5_res;
|
|
||||||
md5_res.Add(&img);
|
|
||||||
const char *const actual_md5 = md5_res.Get();
|
|
||||||
|
|
||||||
// Check md5 match.
|
|
||||||
ASSERT_STREQ(expected_md5, actual_md5) << "MD5 checksums don't match";
|
|
||||||
}
|
|
||||||
|
|
||||||
libvpx_test::WebMVideoSource *video_;
|
|
||||||
libvpx_test::VP9Decoder *decoder_;
|
|
||||||
FILE *md5_file_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_F(ByteAlignmentTest, SwitchByteAlignment) {
|
|
||||||
const int num_elements = 14;
|
|
||||||
const int byte_alignments[] = { 0, 32, 64, 128, 256, 512, 1024,
|
|
||||||
0, 1024, 32, 512, 64, 256, 128 };
|
|
||||||
|
|
||||||
for (int i = 0; i < num_elements; ++i) {
|
|
||||||
SetByteAlignment(byte_alignments[i], VPX_CODEC_OK);
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame(byte_alignments[i]));
|
|
||||||
}
|
|
||||||
SetByteAlignment(byte_alignments[0], VPX_CODEC_OK);
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames(byte_alignments[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ByteAlignmentTest, TestAlignment) {
|
|
||||||
const ByteAlignmentTestParam t = GetParam();
|
|
||||||
SetByteAlignment(t.byte_alignment, t.expected_value);
|
|
||||||
if (t.decode_remaining)
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames(t.byte_alignment));
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(Alignments, ByteAlignmentTest,
|
|
||||||
::testing::ValuesIn(kBaTestParams));
|
|
||||||
|
|
||||||
#endif // CONFIG_WEBM_IO
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
@@ -13,10 +13,10 @@
|
|||||||
#include "./vpx_config.h"
|
#include "./vpx_config.h"
|
||||||
#include "vpx/vpx_decoder.h"
|
#include "vpx/vpx_decoder.h"
|
||||||
#include "vpx/vpx_encoder.h"
|
#include "vpx/vpx_encoder.h"
|
||||||
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
|
#if CONFIG_VP10_ENCODER
|
||||||
#include "vpx/vp8cx.h"
|
#include "vpx/vp8cx.h"
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER
|
#if CONFIG_VP10_DECODER
|
||||||
#include "vpx/vp8dx.h"
|
#include "vpx/vp8dx.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -32,10 +32,13 @@ class CodecFactory {
|
|||||||
|
|
||||||
virtual ~CodecFactory() {}
|
virtual ~CodecFactory() {}
|
||||||
|
|
||||||
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg) const = 0;
|
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
||||||
|
unsigned long deadline) const = 0;
|
||||||
|
|
||||||
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
||||||
const vpx_codec_flags_t flags) const = 0;
|
const vpx_codec_flags_t flags,
|
||||||
|
unsigned long deadline) // NOLINT(runtime/int)
|
||||||
|
const = 0;
|
||||||
|
|
||||||
virtual Encoder* CreateEncoder(vpx_codec_enc_cfg_t cfg,
|
virtual Encoder* CreateEncoder(vpx_codec_enc_cfg_t cfg,
|
||||||
unsigned long deadline,
|
unsigned long deadline,
|
||||||
@@ -51,78 +54,74 @@ class CodecFactory {
|
|||||||
* definition.
|
* definition.
|
||||||
*/
|
*/
|
||||||
template<class T1>
|
template<class T1>
|
||||||
class CodecTestWithParam
|
class CodecTestWithParam : public ::testing::TestWithParam<
|
||||||
: public ::testing::TestWithParam<
|
std::tr1::tuple< const libvpx_test::CodecFactory*, T1 > > {
|
||||||
std::tr1::tuple<const libvpx_test::CodecFactory *, T1> > {};
|
};
|
||||||
|
|
||||||
template<class T1, class T2>
|
template<class T1, class T2>
|
||||||
class CodecTestWith2Params
|
class CodecTestWith2Params : public ::testing::TestWithParam<
|
||||||
: public ::testing::TestWithParam<
|
std::tr1::tuple< const libvpx_test::CodecFactory*, T1, T2 > > {
|
||||||
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2> > {};
|
};
|
||||||
|
|
||||||
template<class T1, class T2, class T3>
|
template<class T1, class T2, class T3>
|
||||||
class CodecTestWith3Params
|
class CodecTestWith3Params : public ::testing::TestWithParam<
|
||||||
: public ::testing::TestWithParam<
|
std::tr1::tuple< const libvpx_test::CodecFactory*, T1, T2, T3 > > {
|
||||||
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2, T3> > {};
|
|
||||||
|
|
||||||
template <class T1, class T2, class T3, class T4>
|
|
||||||
class CodecTestWith4Params
|
|
||||||
: public ::testing::TestWithParam<
|
|
||||||
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2, T3, T4> > {
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VP8 Codec Definitions
|
* VP10 Codec Definitions
|
||||||
*/
|
*/
|
||||||
#if CONFIG_VP8
|
#if CONFIG_VP10
|
||||||
class VP8Decoder : public Decoder {
|
class VP10Decoder : public Decoder {
|
||||||
public:
|
public:
|
||||||
explicit VP8Decoder(vpx_codec_dec_cfg_t cfg) : Decoder(cfg) {}
|
VP10Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
|
||||||
|
: Decoder(cfg, deadline) {}
|
||||||
|
|
||||||
VP8Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag)
|
VP10Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
|
||||||
: Decoder(cfg, flag) {}
|
unsigned long deadline) // NOLINT
|
||||||
|
: Decoder(cfg, flag, deadline) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual vpx_codec_iface_t* CodecInterface() const {
|
virtual vpx_codec_iface_t* CodecInterface() const {
|
||||||
#if CONFIG_VP8_DECODER
|
#if CONFIG_VP10_DECODER
|
||||||
return &vpx_codec_vp8_dx_algo;
|
return &vpx_codec_vp10_dx_algo;
|
||||||
#else
|
#else
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class VP8Encoder : public Encoder {
|
class VP10Encoder : public Encoder {
|
||||||
public:
|
public:
|
||||||
VP8Encoder(vpx_codec_enc_cfg_t cfg, unsigned long deadline,
|
VP10Encoder(vpx_codec_enc_cfg_t cfg, unsigned long deadline,
|
||||||
const unsigned long init_flags, TwopassStatsStore *stats)
|
const unsigned long init_flags, TwopassStatsStore *stats)
|
||||||
: Encoder(cfg, deadline, init_flags, stats) {}
|
: Encoder(cfg, deadline, init_flags, stats) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual vpx_codec_iface_t* CodecInterface() const {
|
virtual vpx_codec_iface_t* CodecInterface() const {
|
||||||
#if CONFIG_VP8_ENCODER
|
#if CONFIG_VP10_ENCODER
|
||||||
return &vpx_codec_vp8_cx_algo;
|
return &vpx_codec_vp10_cx_algo;
|
||||||
#else
|
#else
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class VP8CodecFactory : public CodecFactory {
|
class VP10CodecFactory : public CodecFactory {
|
||||||
public:
|
public:
|
||||||
VP8CodecFactory() : CodecFactory() {}
|
VP10CodecFactory() : CodecFactory() {}
|
||||||
|
|
||||||
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg) const {
|
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
||||||
return CreateDecoder(cfg, 0);
|
unsigned long deadline) const {
|
||||||
|
return CreateDecoder(cfg, 0, deadline);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
||||||
const vpx_codec_flags_t flags) const {
|
const vpx_codec_flags_t flags,
|
||||||
#if CONFIG_VP8_DECODER
|
unsigned long deadline) const { // NOLINT
|
||||||
return new VP8Decoder(cfg, flags);
|
#if CONFIG_VP10_DECODER
|
||||||
|
return new VP10Decoder(cfg, flags, deadline);
|
||||||
#else
|
#else
|
||||||
(void)cfg;
|
|
||||||
(void)flags;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -131,137 +130,34 @@ class VP8CodecFactory : public CodecFactory {
|
|||||||
unsigned long deadline,
|
unsigned long deadline,
|
||||||
const unsigned long init_flags,
|
const unsigned long init_flags,
|
||||||
TwopassStatsStore *stats) const {
|
TwopassStatsStore *stats) const {
|
||||||
#if CONFIG_VP8_ENCODER
|
#if CONFIG_VP10_ENCODER
|
||||||
return new VP8Encoder(cfg, deadline, init_flags, stats);
|
return new VP10Encoder(cfg, deadline, init_flags, stats);
|
||||||
#else
|
#else
|
||||||
(void)cfg;
|
|
||||||
(void)deadline;
|
|
||||||
(void)init_flags;
|
|
||||||
(void)stats;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual vpx_codec_err_t DefaultEncoderConfig(vpx_codec_enc_cfg_t *cfg,
|
virtual vpx_codec_err_t DefaultEncoderConfig(vpx_codec_enc_cfg_t *cfg,
|
||||||
int usage) const {
|
int usage) const {
|
||||||
#if CONFIG_VP8_ENCODER
|
#if CONFIG_VP10_ENCODER
|
||||||
return vpx_codec_enc_config_default(&vpx_codec_vp8_cx_algo, cfg, usage);
|
return vpx_codec_enc_config_default(&vpx_codec_vp10_cx_algo, cfg, usage);
|
||||||
#else
|
#else
|
||||||
(void)cfg;
|
|
||||||
(void)usage;
|
|
||||||
return VPX_CODEC_INCAPABLE;
|
return VPX_CODEC_INCAPABLE;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const libvpx_test::VP8CodecFactory kVP8;
|
const libvpx_test::VP10CodecFactory kVP10;
|
||||||
|
|
||||||
#define VP8_INSTANTIATE_TEST_CASE(test, ...) \
|
#define VP10_INSTANTIATE_TEST_CASE(test, ...)\
|
||||||
INSTANTIATE_TEST_CASE_P( \
|
INSTANTIATE_TEST_CASE_P(VP10, test, \
|
||||||
VP8, test, \
|
|
||||||
::testing::Combine( \
|
::testing::Combine( \
|
||||||
::testing::Values(static_cast<const libvpx_test::CodecFactory*>( \
|
::testing::Values(static_cast<const libvpx_test::CodecFactory*>( \
|
||||||
&libvpx_test::kVP8)), \
|
&libvpx_test::kVP10)), \
|
||||||
__VA_ARGS__))
|
__VA_ARGS__))
|
||||||
#else
|
#else
|
||||||
#define VP8_INSTANTIATE_TEST_CASE(test, ...)
|
#define VP10_INSTANTIATE_TEST_CASE(test, ...)
|
||||||
#endif // CONFIG_VP8
|
#endif // CONFIG_VP10
|
||||||
|
|
||||||
/*
|
|
||||||
* VP9 Codec Definitions
|
|
||||||
*/
|
|
||||||
#if CONFIG_VP9
|
|
||||||
class VP9Decoder : public Decoder {
|
|
||||||
public:
|
|
||||||
explicit VP9Decoder(vpx_codec_dec_cfg_t cfg) : Decoder(cfg) {}
|
|
||||||
|
|
||||||
VP9Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag)
|
|
||||||
: Decoder(cfg, flag) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual vpx_codec_iface_t *CodecInterface() const {
|
|
||||||
#if CONFIG_VP9_DECODER
|
|
||||||
return &vpx_codec_vp9_dx_algo;
|
|
||||||
#else
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class VP9Encoder : public Encoder {
|
|
||||||
public:
|
|
||||||
VP9Encoder(vpx_codec_enc_cfg_t cfg, unsigned long deadline,
|
|
||||||
const unsigned long init_flags, TwopassStatsStore *stats)
|
|
||||||
: Encoder(cfg, deadline, init_flags, stats) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual vpx_codec_iface_t *CodecInterface() const {
|
|
||||||
#if CONFIG_VP9_ENCODER
|
|
||||||
return &vpx_codec_vp9_cx_algo;
|
|
||||||
#else
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class VP9CodecFactory : public CodecFactory {
|
|
||||||
public:
|
|
||||||
VP9CodecFactory() : CodecFactory() {}
|
|
||||||
|
|
||||||
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg) const {
|
|
||||||
return CreateDecoder(cfg, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
|
||||||
const vpx_codec_flags_t flags) const {
|
|
||||||
#if CONFIG_VP9_DECODER
|
|
||||||
return new VP9Decoder(cfg, flags);
|
|
||||||
#else
|
|
||||||
(void)cfg;
|
|
||||||
(void)flags;
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Encoder *CreateEncoder(vpx_codec_enc_cfg_t cfg,
|
|
||||||
unsigned long deadline,
|
|
||||||
const unsigned long init_flags,
|
|
||||||
TwopassStatsStore *stats) const {
|
|
||||||
#if CONFIG_VP9_ENCODER
|
|
||||||
return new VP9Encoder(cfg, deadline, init_flags, stats);
|
|
||||||
#else
|
|
||||||
(void)cfg;
|
|
||||||
(void)deadline;
|
|
||||||
(void)init_flags;
|
|
||||||
(void)stats;
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual vpx_codec_err_t DefaultEncoderConfig(vpx_codec_enc_cfg_t *cfg,
|
|
||||||
int usage) const {
|
|
||||||
#if CONFIG_VP9_ENCODER
|
|
||||||
return vpx_codec_enc_config_default(&vpx_codec_vp9_cx_algo, cfg, usage);
|
|
||||||
#else
|
|
||||||
(void)cfg;
|
|
||||||
(void)usage;
|
|
||||||
return VPX_CODEC_INCAPABLE;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const libvpx_test::VP9CodecFactory kVP9;
|
|
||||||
|
|
||||||
#define VP9_INSTANTIATE_TEST_CASE(test, ...) \
|
|
||||||
INSTANTIATE_TEST_CASE_P( \
|
|
||||||
VP9, test, \
|
|
||||||
::testing::Combine( \
|
|
||||||
::testing::Values(static_cast<const libvpx_test::CodecFactory *>( \
|
|
||||||
&libvpx_test::kVP9)), \
|
|
||||||
__VA_ARGS__))
|
|
||||||
#else
|
|
||||||
#define VP9_INSTANTIATE_TEST_CASE(test, ...)
|
|
||||||
#endif // CONFIG_VP9
|
|
||||||
|
|
||||||
} // namespace libvpx_test
|
} // namespace libvpx_test
|
||||||
#endif // TEST_CODEC_FACTORY_H_
|
#endif // TEST_CODEC_FACTORY_H_
|
||||||
|
|||||||
@@ -1,182 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
|
|
||||||
#include "test/acm_random.h"
|
|
||||||
#include "test/buffer.h"
|
|
||||||
#include "test/register_state_check.h"
|
|
||||||
#include "vpx_ports/vpx_timer.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
using ::libvpx_test::ACMRandom;
|
|
||||||
using ::libvpx_test::Buffer;
|
|
||||||
|
|
||||||
typedef void (*AvgPredFunc)(uint8_t *a, const uint8_t *b, int w, int h,
|
|
||||||
const uint8_t *c, int c_stride);
|
|
||||||
|
|
||||||
uint8_t avg_with_rounding(uint8_t a, uint8_t b) { return (a + b + 1) >> 1; }
|
|
||||||
|
|
||||||
void reference_pred(const Buffer<uint8_t> &pred, const Buffer<uint8_t> &ref,
|
|
||||||
int width, int height, Buffer<uint8_t> *avg) {
|
|
||||||
for (int y = 0; y < height; ++y) {
|
|
||||||
for (int x = 0; x < width; ++x) {
|
|
||||||
avg->TopLeftPixel()[y * avg->stride() + x] =
|
|
||||||
avg_with_rounding(pred.TopLeftPixel()[y * pred.stride() + x],
|
|
||||||
ref.TopLeftPixel()[y * ref.stride() + x]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class AvgPredTest : public ::testing::TestWithParam<AvgPredFunc> {
|
|
||||||
public:
|
|
||||||
virtual void SetUp() {
|
|
||||||
avg_pred_func_ = GetParam();
|
|
||||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
AvgPredFunc avg_pred_func_;
|
|
||||||
ACMRandom rnd_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(AvgPredTest, SizeCombinations) {
|
|
||||||
// This is called as part of the sub pixel variance. As such it must be one of
|
|
||||||
// the variance block sizes.
|
|
||||||
|
|
||||||
for (int width_pow = 2; width_pow <= 6; ++width_pow) {
|
|
||||||
for (int height_pow = width_pow - 1; height_pow <= width_pow + 1;
|
|
||||||
++height_pow) {
|
|
||||||
// Don't test 4x2 or 64x128
|
|
||||||
if (height_pow == 1 || height_pow == 7) continue;
|
|
||||||
|
|
||||||
// The sse2 special-cases when ref width == stride, so make sure to test
|
|
||||||
// it.
|
|
||||||
for (int ref_padding = 0; ref_padding < 2; ref_padding++) {
|
|
||||||
const int width = 1 << width_pow;
|
|
||||||
const int height = 1 << height_pow;
|
|
||||||
// Only the reference buffer may have a stride not equal to width.
|
|
||||||
Buffer<uint8_t> ref =
|
|
||||||
Buffer<uint8_t>(width, height, ref_padding ? 8 : 0);
|
|
||||||
ASSERT_TRUE(ref.Init());
|
|
||||||
Buffer<uint8_t> pred = Buffer<uint8_t>(width, height, 0, 16);
|
|
||||||
ASSERT_TRUE(pred.Init());
|
|
||||||
Buffer<uint8_t> avg_ref = Buffer<uint8_t>(width, height, 0, 16);
|
|
||||||
ASSERT_TRUE(avg_ref.Init());
|
|
||||||
Buffer<uint8_t> avg_chk = Buffer<uint8_t>(width, height, 0, 16);
|
|
||||||
ASSERT_TRUE(avg_chk.Init());
|
|
||||||
|
|
||||||
ref.Set(&rnd_, &ACMRandom::Rand8);
|
|
||||||
pred.Set(&rnd_, &ACMRandom::Rand8);
|
|
||||||
|
|
||||||
reference_pred(pred, ref, width, height, &avg_ref);
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
avg_pred_func_(avg_chk.TopLeftPixel(), pred.TopLeftPixel(), width,
|
|
||||||
height, ref.TopLeftPixel(), ref.stride()));
|
|
||||||
|
|
||||||
EXPECT_TRUE(avg_chk.CheckValues(avg_ref));
|
|
||||||
if (HasFailure()) {
|
|
||||||
printf("Width: %d Height: %d\n", width, height);
|
|
||||||
avg_chk.PrintDifference(avg_ref);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(AvgPredTest, CompareReferenceRandom) {
|
|
||||||
const int width = 64;
|
|
||||||
const int height = 32;
|
|
||||||
Buffer<uint8_t> ref = Buffer<uint8_t>(width, height, 8);
|
|
||||||
ASSERT_TRUE(ref.Init());
|
|
||||||
Buffer<uint8_t> pred = Buffer<uint8_t>(width, height, 0, 16);
|
|
||||||
ASSERT_TRUE(pred.Init());
|
|
||||||
Buffer<uint8_t> avg_ref = Buffer<uint8_t>(width, height, 0, 16);
|
|
||||||
ASSERT_TRUE(avg_ref.Init());
|
|
||||||
Buffer<uint8_t> avg_chk = Buffer<uint8_t>(width, height, 0, 16);
|
|
||||||
ASSERT_TRUE(avg_chk.Init());
|
|
||||||
|
|
||||||
for (int i = 0; i < 500; ++i) {
|
|
||||||
ref.Set(&rnd_, &ACMRandom::Rand8);
|
|
||||||
pred.Set(&rnd_, &ACMRandom::Rand8);
|
|
||||||
|
|
||||||
reference_pred(pred, ref, width, height, &avg_ref);
|
|
||||||
ASM_REGISTER_STATE_CHECK(avg_pred_func_(avg_chk.TopLeftPixel(),
|
|
||||||
pred.TopLeftPixel(), width, height,
|
|
||||||
ref.TopLeftPixel(), ref.stride()));
|
|
||||||
EXPECT_TRUE(avg_chk.CheckValues(avg_ref));
|
|
||||||
if (HasFailure()) {
|
|
||||||
printf("Width: %d Height: %d\n", width, height);
|
|
||||||
avg_chk.PrintDifference(avg_ref);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(AvgPredTest, DISABLED_Speed) {
|
|
||||||
for (int width_pow = 2; width_pow <= 6; ++width_pow) {
|
|
||||||
for (int height_pow = width_pow - 1; height_pow <= width_pow + 1;
|
|
||||||
++height_pow) {
|
|
||||||
// Don't test 4x2 or 64x128
|
|
||||||
if (height_pow == 1 || height_pow == 7) continue;
|
|
||||||
|
|
||||||
for (int ref_padding = 0; ref_padding < 2; ref_padding++) {
|
|
||||||
const int width = 1 << width_pow;
|
|
||||||
const int height = 1 << height_pow;
|
|
||||||
Buffer<uint8_t> ref =
|
|
||||||
Buffer<uint8_t>(width, height, ref_padding ? 8 : 0);
|
|
||||||
ASSERT_TRUE(ref.Init());
|
|
||||||
Buffer<uint8_t> pred = Buffer<uint8_t>(width, height, 0, 16);
|
|
||||||
ASSERT_TRUE(pred.Init());
|
|
||||||
Buffer<uint8_t> avg = Buffer<uint8_t>(width, height, 0, 16);
|
|
||||||
ASSERT_TRUE(avg.Init());
|
|
||||||
|
|
||||||
ref.Set(&rnd_, &ACMRandom::Rand8);
|
|
||||||
pred.Set(&rnd_, &ACMRandom::Rand8);
|
|
||||||
|
|
||||||
vpx_usec_timer timer;
|
|
||||||
vpx_usec_timer_start(&timer);
|
|
||||||
for (int i = 0; i < 10000000 / (width * height); ++i) {
|
|
||||||
avg_pred_func_(avg.TopLeftPixel(), pred.TopLeftPixel(), width, height,
|
|
||||||
ref.TopLeftPixel(), ref.stride());
|
|
||||||
}
|
|
||||||
vpx_usec_timer_mark(&timer);
|
|
||||||
|
|
||||||
const int elapsed_time =
|
|
||||||
static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
|
||||||
printf("Average Test (ref_padding: %d) %dx%d time: %5d us\n",
|
|
||||||
ref_padding, width, height, elapsed_time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(C, AvgPredTest,
|
|
||||||
::testing::Values(&vpx_comp_avg_pred_c));
|
|
||||||
|
|
||||||
#if HAVE_SSE2
|
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, AvgPredTest,
|
|
||||||
::testing::Values(&vpx_comp_avg_pred_sse2));
|
|
||||||
#endif // HAVE_SSE2
|
|
||||||
|
|
||||||
#if HAVE_NEON
|
|
||||||
INSTANTIATE_TEST_CASE_P(NEON, AvgPredTest,
|
|
||||||
::testing::Values(&vpx_comp_avg_pred_neon));
|
|
||||||
#endif // HAVE_NEON
|
|
||||||
|
|
||||||
#if HAVE_VSX
|
|
||||||
INSTANTIATE_TEST_CASE_P(VSX, AvgPredTest,
|
|
||||||
::testing::Values(&vpx_comp_avg_pred_vsx));
|
|
||||||
#endif // HAVE_VSX
|
|
||||||
} // namespace
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
#include "test/codec_factory.h"
|
|
||||||
#include "test/encode_test_driver.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
#include "test/video_source.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
class ConfigTest
|
|
||||||
: public ::libvpx_test::EncoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
|
||||||
protected:
|
|
||||||
ConfigTest()
|
|
||||||
: EncoderTest(GET_PARAM(0)), frame_count_in_(0), frame_count_out_(0),
|
|
||||||
frame_count_max_(0) {}
|
|
||||||
virtual ~ConfigTest() {}
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
|
||||||
InitializeConfig();
|
|
||||||
SetMode(GET_PARAM(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
|
||||||
frame_count_in_ = 0;
|
|
||||||
frame_count_out_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource * /*video*/) {
|
|
||||||
++frame_count_in_;
|
|
||||||
abort_ |= (frame_count_in_ >= frame_count_max_);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {
|
|
||||||
++frame_count_out_;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int frame_count_in_;
|
|
||||||
unsigned int frame_count_out_;
|
|
||||||
unsigned int frame_count_max_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(ConfigTest, LagIsDisabled) {
|
|
||||||
frame_count_max_ = 2;
|
|
||||||
cfg_.g_lag_in_frames = 15;
|
|
||||||
|
|
||||||
libvpx_test::DummyVideoSource video;
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
|
|
||||||
EXPECT_EQ(frame_count_in_, frame_count_out_);
|
|
||||||
}
|
|
||||||
|
|
||||||
VP8_INSTANTIATE_TEST_CASE(ConfigTest, ONE_PASS_TEST_MODES);
|
|
||||||
} // namespace
|
|
||||||
@@ -1,214 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#if CONFIG_VP9_ENCODER
|
|
||||||
#include "./vp9_rtcd.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "test/acm_random.h"
|
|
||||||
#include "test/clear_system_state.h"
|
|
||||||
#include "test/register_state_check.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
#include "vpx_dsp/ssim.h"
|
|
||||||
#include "vpx_mem/vpx_mem.h"
|
|
||||||
|
|
||||||
extern "C" double vpx_get_ssim_metrics(uint8_t *img1, int img1_pitch,
|
|
||||||
uint8_t *img2, int img2_pitch, int width,
|
|
||||||
int height, Ssimv *sv2, Metrics *m,
|
|
||||||
int do_inconsistency);
|
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
class ConsistencyTestBase : public ::testing::Test {
|
|
||||||
public:
|
|
||||||
ConsistencyTestBase(int width, int height) : width_(width), height_(height) {}
|
|
||||||
|
|
||||||
static void SetUpTestCase() {
|
|
||||||
source_data_[0] = reinterpret_cast<uint8_t *>(
|
|
||||||
vpx_memalign(kDataAlignment, kDataBufferSize));
|
|
||||||
reference_data_[0] = reinterpret_cast<uint8_t *>(
|
|
||||||
vpx_memalign(kDataAlignment, kDataBufferSize));
|
|
||||||
source_data_[1] = reinterpret_cast<uint8_t *>(
|
|
||||||
vpx_memalign(kDataAlignment, kDataBufferSize));
|
|
||||||
reference_data_[1] = reinterpret_cast<uint8_t *>(
|
|
||||||
vpx_memalign(kDataAlignment, kDataBufferSize));
|
|
||||||
ssim_array_ = new Ssimv[kDataBufferSize / 16];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ClearSsim() { memset(ssim_array_, 0, kDataBufferSize / 16); }
|
|
||||||
static void TearDownTestCase() {
|
|
||||||
vpx_free(source_data_[0]);
|
|
||||||
source_data_[0] = NULL;
|
|
||||||
vpx_free(reference_data_[0]);
|
|
||||||
reference_data_[0] = NULL;
|
|
||||||
vpx_free(source_data_[1]);
|
|
||||||
source_data_[1] = NULL;
|
|
||||||
vpx_free(reference_data_[1]);
|
|
||||||
reference_data_[1] = NULL;
|
|
||||||
|
|
||||||
delete[] ssim_array_;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Handle frames up to 640x480
|
|
||||||
static const int kDataAlignment = 16;
|
|
||||||
static const int kDataBufferSize = 640 * 480;
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
|
||||||
source_stride_ = (width_ + 31) & ~31;
|
|
||||||
reference_stride_ = width_ * 2;
|
|
||||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
|
||||||
}
|
|
||||||
|
|
||||||
void FillRandom(uint8_t *data, int stride, int width, int height) {
|
|
||||||
for (int h = 0; h < height; ++h) {
|
|
||||||
for (int w = 0; w < width; ++w) {
|
|
||||||
data[h * stride + w] = rnd_.Rand8();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FillRandom(uint8_t *data, int stride) {
|
|
||||||
FillRandom(data, stride, width_, height_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Copy(uint8_t *reference, uint8_t *source) {
|
|
||||||
memcpy(reference, source, kDataBufferSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Blur(uint8_t *data, int stride, int taps) {
|
|
||||||
int sum = 0;
|
|
||||||
int half_taps = taps / 2;
|
|
||||||
for (int h = 0; h < height_; ++h) {
|
|
||||||
for (int w = 0; w < taps; ++w) {
|
|
||||||
sum += data[w + h * stride];
|
|
||||||
}
|
|
||||||
for (int w = taps; w < width_; ++w) {
|
|
||||||
sum += data[w + h * stride] - data[w - taps + h * stride];
|
|
||||||
data[w - half_taps + h * stride] = (sum + half_taps) / taps;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int w = 0; w < width_; ++w) {
|
|
||||||
for (int h = 0; h < taps; ++h) {
|
|
||||||
sum += data[h + w * stride];
|
|
||||||
}
|
|
||||||
for (int h = taps; h < height_; ++h) {
|
|
||||||
sum += data[w + h * stride] - data[(h - taps) * stride + w];
|
|
||||||
data[(h - half_taps) * stride + w] = (sum + half_taps) / taps;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int width_, height_;
|
|
||||||
static uint8_t *source_data_[2];
|
|
||||||
int source_stride_;
|
|
||||||
static uint8_t *reference_data_[2];
|
|
||||||
int reference_stride_;
|
|
||||||
static Ssimv *ssim_array_;
|
|
||||||
Metrics metrics_;
|
|
||||||
|
|
||||||
ACMRandom rnd_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if CONFIG_VP9_ENCODER
|
|
||||||
typedef std::tr1::tuple<int, int> ConsistencyParam;
|
|
||||||
class ConsistencyVP9Test
|
|
||||||
: public ConsistencyTestBase,
|
|
||||||
public ::testing::WithParamInterface<ConsistencyParam> {
|
|
||||||
public:
|
|
||||||
ConsistencyVP9Test() : ConsistencyTestBase(GET_PARAM(0), GET_PARAM(1)) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
double CheckConsistency(int frame) {
|
|
||||||
EXPECT_LT(frame, 2) << "Frame to check has to be less than 2.";
|
|
||||||
return vpx_get_ssim_metrics(source_data_[frame], source_stride_,
|
|
||||||
reference_data_[frame], reference_stride_,
|
|
||||||
width_, height_, ssim_array_, &metrics_, 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif // CONFIG_VP9_ENCODER
|
|
||||||
|
|
||||||
uint8_t *ConsistencyTestBase::source_data_[2] = { NULL, NULL };
|
|
||||||
uint8_t *ConsistencyTestBase::reference_data_[2] = { NULL, NULL };
|
|
||||||
Ssimv *ConsistencyTestBase::ssim_array_ = NULL;
|
|
||||||
|
|
||||||
#if CONFIG_VP9_ENCODER
|
|
||||||
TEST_P(ConsistencyVP9Test, ConsistencyIsZero) {
|
|
||||||
FillRandom(source_data_[0], source_stride_);
|
|
||||||
Copy(source_data_[1], source_data_[0]);
|
|
||||||
Copy(reference_data_[0], source_data_[0]);
|
|
||||||
Blur(reference_data_[0], reference_stride_, 3);
|
|
||||||
Copy(reference_data_[1], source_data_[0]);
|
|
||||||
Blur(reference_data_[1], reference_stride_, 3);
|
|
||||||
|
|
||||||
double inconsistency = CheckConsistency(1);
|
|
||||||
inconsistency = CheckConsistency(0);
|
|
||||||
EXPECT_EQ(inconsistency, 0.0)
|
|
||||||
<< "Should have 0 inconsistency if they are exactly the same.";
|
|
||||||
|
|
||||||
// If sources are not consistent reference frames inconsistency should
|
|
||||||
// be less than if the source is consistent.
|
|
||||||
FillRandom(source_data_[0], source_stride_);
|
|
||||||
FillRandom(source_data_[1], source_stride_);
|
|
||||||
FillRandom(reference_data_[0], reference_stride_);
|
|
||||||
FillRandom(reference_data_[1], reference_stride_);
|
|
||||||
CheckConsistency(0);
|
|
||||||
inconsistency = CheckConsistency(1);
|
|
||||||
|
|
||||||
Copy(source_data_[1], source_data_[0]);
|
|
||||||
CheckConsistency(0);
|
|
||||||
double inconsistency2 = CheckConsistency(1);
|
|
||||||
EXPECT_LT(inconsistency, inconsistency2)
|
|
||||||
<< "Should have less inconsistency if source itself is inconsistent.";
|
|
||||||
|
|
||||||
// Less of a blur should be less inconsistent than more blur coming off a
|
|
||||||
// a frame with no blur.
|
|
||||||
ClearSsim();
|
|
||||||
FillRandom(source_data_[0], source_stride_);
|
|
||||||
Copy(source_data_[1], source_data_[0]);
|
|
||||||
Copy(reference_data_[0], source_data_[0]);
|
|
||||||
Copy(reference_data_[1], source_data_[0]);
|
|
||||||
Blur(reference_data_[1], reference_stride_, 4);
|
|
||||||
CheckConsistency(0);
|
|
||||||
inconsistency = CheckConsistency(1);
|
|
||||||
ClearSsim();
|
|
||||||
Copy(reference_data_[1], source_data_[0]);
|
|
||||||
Blur(reference_data_[1], reference_stride_, 8);
|
|
||||||
CheckConsistency(0);
|
|
||||||
inconsistency2 = CheckConsistency(1);
|
|
||||||
|
|
||||||
EXPECT_LT(inconsistency, inconsistency2)
|
|
||||||
<< "Stronger Blur should produce more inconsistency.";
|
|
||||||
}
|
|
||||||
#endif // CONFIG_VP9_ENCODER
|
|
||||||
|
|
||||||
using std::tr1::make_tuple;
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// C functions
|
|
||||||
|
|
||||||
#if CONFIG_VP9_ENCODER
|
|
||||||
const ConsistencyParam c_vp9_tests[] = {
|
|
||||||
make_tuple(320, 240), make_tuple(318, 242), make_tuple(318, 238),
|
|
||||||
};
|
|
||||||
INSTANTIATE_TEST_CASE_P(C, ConsistencyVP9Test,
|
|
||||||
::testing::ValuesIn(c_vp9_tests));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -23,9 +23,11 @@ class CpuSpeedTest
|
|||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||||
protected:
|
protected:
|
||||||
CpuSpeedTest()
|
CpuSpeedTest()
|
||||||
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
|
: EncoderTest(GET_PARAM(0)),
|
||||||
set_cpu_used_(GET_PARAM(2)), min_psnr_(kMaxPSNR),
|
encoding_mode_(GET_PARAM(1)),
|
||||||
tune_content_(VP9E_CONTENT_DEFAULT) {}
|
set_cpu_used_(GET_PARAM(2)),
|
||||||
|
min_psnr_(kMaxPSNR),
|
||||||
|
tune_content_(VPX_CONTENT_DEFAULT) {}
|
||||||
virtual ~CpuSpeedTest() {}
|
virtual ~CpuSpeedTest() {}
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
@@ -40,7 +42,9 @@ class CpuSpeedTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void BeginPassHook(unsigned int /*pass*/) { min_psnr_ = kMaxPSNR; }
|
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||||
|
min_psnr_ = kMaxPSNR;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||||
::libvpx_test::Encoder *encoder) {
|
::libvpx_test::Encoder *encoder) {
|
||||||
@@ -57,7 +61,8 @@ class CpuSpeedTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||||
if (pkt->data.psnr.psnr[0] < min_psnr_) min_psnr_ = pkt->data.psnr.psnr[0];
|
if (pkt->data.psnr.psnr[0] < min_psnr_)
|
||||||
|
min_psnr_ = pkt->data.psnr.psnr[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
::libvpx_test::TestMode encoding_mode_;
|
::libvpx_test::TestMode encoding_mode_;
|
||||||
@@ -78,7 +83,7 @@ TEST_P(CpuSpeedTest, TestQ0) {
|
|||||||
cfg_.rc_min_quantizer = 0;
|
cfg_.rc_min_quantizer = 0;
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||||
20);
|
10);
|
||||||
|
|
||||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||||
|
|
||||||
@@ -87,7 +92,7 @@ TEST_P(CpuSpeedTest, TestQ0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(CpuSpeedTest, TestScreencastQ0) {
|
TEST_P(CpuSpeedTest, TestScreencastQ0) {
|
||||||
::libvpx_test::Y4mVideoSource video("screendata.y4m", 0, 25);
|
::libvpx_test::Y4mVideoSource video("screendata.y4m", 0, 10);
|
||||||
cfg_.g_timebase = video.timebase();
|
cfg_.g_timebase = video.timebase();
|
||||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
||||||
@@ -102,14 +107,14 @@ TEST_P(CpuSpeedTest, TestScreencastQ0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(CpuSpeedTest, TestTuneScreen) {
|
TEST_P(CpuSpeedTest, TestTuneScreen) {
|
||||||
::libvpx_test::Y4mVideoSource video("screendata.y4m", 0, 25);
|
::libvpx_test::Y4mVideoSource video("screendata.y4m", 0, 10);
|
||||||
cfg_.g_timebase = video.timebase();
|
cfg_.g_timebase = video.timebase();
|
||||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||||
cfg_.rc_2pass_vbr_minsection_pct = 2000;
|
cfg_.rc_2pass_vbr_minsection_pct = 2000;
|
||||||
cfg_.rc_target_bitrate = 2000;
|
cfg_.rc_target_bitrate = 2000;
|
||||||
cfg_.rc_max_quantizer = 63;
|
cfg_.rc_max_quantizer = 63;
|
||||||
cfg_.rc_min_quantizer = 0;
|
cfg_.rc_min_quantizer = 0;
|
||||||
tune_content_ = VP9E_CONTENT_SCREEN;
|
tune_content_ = VPX_CONTENT_SCREEN;
|
||||||
|
|
||||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||||
|
|
||||||
@@ -128,7 +133,7 @@ TEST_P(CpuSpeedTest, TestEncodeHighBitrate) {
|
|||||||
cfg_.rc_min_quantizer = 0;
|
cfg_.rc_min_quantizer = 0;
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||||
20);
|
10);
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
}
|
||||||
@@ -143,14 +148,13 @@ TEST_P(CpuSpeedTest, TestLowBitrate) {
|
|||||||
cfg_.rc_min_quantizer = 40;
|
cfg_.rc_min_quantizer = 40;
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||||
20);
|
10);
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
}
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(CpuSpeedTest,
|
VP10_INSTANTIATE_TEST_CASE(
|
||||||
::testing::Values(::libvpx_test::kTwoPassGood,
|
CpuSpeedTest,
|
||||||
::libvpx_test::kOnePassGood,
|
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood),
|
||||||
::libvpx_test::kRealTime),
|
::testing::Range(0, 3));
|
||||||
::testing::Range(0, 9));
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
131
test/cq_test.cc
131
test/cq_test.cc
@@ -1,131 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
#include <cmath>
|
|
||||||
#include <map>
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
#include "test/codec_factory.h"
|
|
||||||
#include "test/encode_test_driver.h"
|
|
||||||
#include "test/i420_video_source.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
// CQ level range: [kCQLevelMin, kCQLevelMax).
|
|
||||||
const int kCQLevelMin = 4;
|
|
||||||
const int kCQLevelMax = 63;
|
|
||||||
const int kCQLevelStep = 8;
|
|
||||||
const unsigned int kCQTargetBitrate = 2000;
|
|
||||||
|
|
||||||
class CQTest : public ::libvpx_test::EncoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWithParam<int> {
|
|
||||||
public:
|
|
||||||
// maps the cqlevel to the bitrate produced.
|
|
||||||
typedef std::map<int, uint32_t> BitrateMap;
|
|
||||||
|
|
||||||
static void SetUpTestCase() { bitrates_.clear(); }
|
|
||||||
|
|
||||||
static void TearDownTestCase() {
|
|
||||||
ASSERT_TRUE(!HasFailure())
|
|
||||||
<< "skipping bitrate validation due to earlier failure.";
|
|
||||||
uint32_t prev_actual_bitrate = kCQTargetBitrate;
|
|
||||||
for (BitrateMap::const_iterator iter = bitrates_.begin();
|
|
||||||
iter != bitrates_.end(); ++iter) {
|
|
||||||
const uint32_t cq_actual_bitrate = iter->second;
|
|
||||||
EXPECT_LE(cq_actual_bitrate, prev_actual_bitrate)
|
|
||||||
<< "cq_level: " << iter->first
|
|
||||||
<< ", bitrate should decrease with increase in CQ level.";
|
|
||||||
prev_actual_bitrate = cq_actual_bitrate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
CQTest() : EncoderTest(GET_PARAM(0)), cq_level_(GET_PARAM(1)) {
|
|
||||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~CQTest() {}
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
|
||||||
InitializeConfig();
|
|
||||||
SetMode(libvpx_test::kTwoPassGood);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
|
||||||
file_size_ = 0;
|
|
||||||
psnr_ = 0.0;
|
|
||||||
n_frames_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
|
||||||
libvpx_test::Encoder *encoder) {
|
|
||||||
if (video->frame() == 1) {
|
|
||||||
if (cfg_.rc_end_usage == VPX_CQ) {
|
|
||||||
encoder->Control(VP8E_SET_CQ_LEVEL, cq_level_);
|
|
||||||
}
|
|
||||||
encoder->Control(VP8E_SET_CPUUSED, 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
|
||||||
psnr_ += pow(10.0, pkt->data.psnr.psnr[0] / 10.0);
|
|
||||||
n_frames_++;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
|
||||||
file_size_ += pkt->data.frame.sz;
|
|
||||||
}
|
|
||||||
|
|
||||||
double GetLinearPSNROverBitrate() const {
|
|
||||||
double avg_psnr = log10(psnr_ / n_frames_) * 10.0;
|
|
||||||
return pow(10.0, avg_psnr / 10.0) / file_size_;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cq_level() const { return cq_level_; }
|
|
||||||
size_t file_size() const { return file_size_; }
|
|
||||||
int n_frames() const { return n_frames_; }
|
|
||||||
|
|
||||||
static BitrateMap bitrates_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
int cq_level_;
|
|
||||||
size_t file_size_;
|
|
||||||
double psnr_;
|
|
||||||
int n_frames_;
|
|
||||||
};
|
|
||||||
|
|
||||||
CQTest::BitrateMap CQTest::bitrates_;
|
|
||||||
|
|
||||||
TEST_P(CQTest, LinearPSNRIsHigherForCQLevel) {
|
|
||||||
const vpx_rational timebase = { 33333333, 1000000000 };
|
|
||||||
cfg_.g_timebase = timebase;
|
|
||||||
cfg_.rc_target_bitrate = kCQTargetBitrate;
|
|
||||||
cfg_.g_lag_in_frames = 25;
|
|
||||||
|
|
||||||
cfg_.rc_end_usage = VPX_CQ;
|
|
||||||
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
|
||||||
timebase.den, timebase.num, 0, 30);
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
const double cq_psnr_lin = GetLinearPSNROverBitrate();
|
|
||||||
const unsigned int cq_actual_bitrate =
|
|
||||||
static_cast<unsigned int>(file_size()) * 8 * 30 / (n_frames() * 1000);
|
|
||||||
EXPECT_LE(cq_actual_bitrate, kCQTargetBitrate);
|
|
||||||
bitrates_[cq_level()] = cq_actual_bitrate;
|
|
||||||
|
|
||||||
// try targeting the approximate same bitrate with VBR mode
|
|
||||||
cfg_.rc_end_usage = VPX_VBR;
|
|
||||||
cfg_.rc_target_bitrate = cq_actual_bitrate;
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
const double vbr_psnr_lin = GetLinearPSNROverBitrate();
|
|
||||||
EXPECT_GE(cq_psnr_lin, vbr_psnr_lin);
|
|
||||||
}
|
|
||||||
|
|
||||||
VP8_INSTANTIATE_TEST_CASE(CQTest, ::testing::Range(kCQLevelMin, kCQLevelMax,
|
|
||||||
kCQLevelStep));
|
|
||||||
} // namespace
|
|
||||||
@@ -27,7 +27,12 @@ cx_set_ref_verify_environment() {
|
|||||||
# $1 is the codec name.
|
# $1 is the codec name.
|
||||||
vpx_set_ref() {
|
vpx_set_ref() {
|
||||||
local codec="$1"
|
local codec="$1"
|
||||||
local encoder="${LIBVPX_BIN_PATH}/${codec}cx_set_ref${VPX_TEST_EXE_SUFFIX}"
|
local encoder="${LIBVPX_BIN_PATH}/vpxcx_set_ref${VPX_TEST_EXE_SUFFIX}"
|
||||||
|
|
||||||
|
if [ "$codec" = "vp8" ]; then
|
||||||
|
encoder="${LIBVPX_BIN_PATH}/vp8cx_set_ref${VPX_TEST_EXE_SUFFIX}"
|
||||||
|
fi
|
||||||
|
|
||||||
local output_file="${VPX_TEST_OUTPUT_DIR}/${codec}cx_set_ref_${codec}.ivf"
|
local output_file="${VPX_TEST_OUTPUT_DIR}/${codec}cx_set_ref_${codec}.ivf"
|
||||||
local ref_frame_num=90
|
local ref_frame_num=90
|
||||||
|
|
||||||
@@ -36,9 +41,15 @@ vpx_set_ref() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$codec" = "vp8" ]; then
|
||||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "${YUV_RAW_INPUT_WIDTH}" \
|
eval "${VPX_TEST_PREFIX}" "${encoder}" "${YUV_RAW_INPUT_WIDTH}" \
|
||||||
"${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" \
|
"${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" \
|
||||||
"${ref_frame_num}" ${devnull}
|
"${ref_frame_num}" ${devnull}
|
||||||
|
else
|
||||||
|
eval "${VPX_TEST_PREFIX}" "${encoder}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \
|
||||||
|
"${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" \
|
||||||
|
"${ref_frame_num}" ${devnull}
|
||||||
|
fi
|
||||||
|
|
||||||
[ -e "${output_file}" ] || return 1
|
[ -e "${output_file}" ] || return 1
|
||||||
}
|
}
|
||||||
@@ -55,6 +66,12 @@ cx_set_ref_vp9() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
cx_set_ref_tests="cx_set_ref_vp8 cx_set_ref_vp9"
|
cx_set_ref_vp10() {
|
||||||
|
if [ "$(vp10_encode_available)" = "yes" ]; then
|
||||||
|
vpx_set_ref vp10 || return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cx_set_ref_tests="cx_set_ref_vp8 cx_set_ref_vp9 cx_set_ref_vp10"
|
||||||
|
|
||||||
run_tests cx_set_ref_verify_environment "${cx_set_ref_tests}"
|
run_tests cx_set_ref_verify_environment "${cx_set_ref_tests}"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -14,14 +14,14 @@
|
|||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vp9_rtcd.h"
|
#include "./vp10_rtcd.h"
|
||||||
#include "./vpx_dsp_rtcd.h"
|
#include "./vpx_dsp_rtcd.h"
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
#include "vp9/common/vp9_entropy.h"
|
#include "vp10/common/entropy.h"
|
||||||
#include "vp9/common/vp9_scan.h"
|
#include "vp10/common/scan.h"
|
||||||
#include "vpx/vpx_codec.h"
|
#include "vpx/vpx_codec.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
#include "vpx_ports/mem.h"
|
#include "vpx_ports/mem.h"
|
||||||
@@ -208,17 +208,21 @@ void reference_16x16_dct_2d(int16_t input[256], double output[256]) {
|
|||||||
// First transform columns
|
// First transform columns
|
||||||
for (int i = 0; i < 16; ++i) {
|
for (int i = 0; i < 16; ++i) {
|
||||||
double temp_in[16], temp_out[16];
|
double temp_in[16], temp_out[16];
|
||||||
for (int j = 0; j < 16; ++j) temp_in[j] = input[j * 16 + i];
|
for (int j = 0; j < 16; ++j)
|
||||||
|
temp_in[j] = input[j * 16 + i];
|
||||||
butterfly_16x16_dct_1d(temp_in, temp_out);
|
butterfly_16x16_dct_1d(temp_in, temp_out);
|
||||||
for (int j = 0; j < 16; ++j) output[j * 16 + i] = temp_out[j];
|
for (int j = 0; j < 16; ++j)
|
||||||
|
output[j * 16 + i] = temp_out[j];
|
||||||
}
|
}
|
||||||
// Then transform rows
|
// Then transform rows
|
||||||
for (int i = 0; i < 16; ++i) {
|
for (int i = 0; i < 16; ++i) {
|
||||||
double temp_in[16], temp_out[16];
|
double temp_in[16], temp_out[16];
|
||||||
for (int j = 0; j < 16; ++j) temp_in[j] = output[j + i * 16];
|
for (int j = 0; j < 16; ++j)
|
||||||
|
temp_in[j] = output[j + i * 16];
|
||||||
butterfly_16x16_dct_1d(temp_in, temp_out);
|
butterfly_16x16_dct_1d(temp_in, temp_out);
|
||||||
// Scale by some magic number
|
// Scale by some magic number
|
||||||
for (int j = 0; j < 16; ++j) output[j + i * 16] = temp_out[j] / 2;
|
for (int j = 0; j < 16; ++j)
|
||||||
|
output[j + i * 16] = temp_out[j]/2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,68 +248,69 @@ void idct16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
|
|||||||
vpx_idct16x16_256_add_c(in, dest, stride);
|
vpx_idct16x16_256_add_c(in, dest, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fht16x16_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
void fht16x16_ref(const int16_t *in, tran_low_t *out, int stride,
|
||||||
vp9_fht16x16_c(in, out, stride, tx_type);
|
int tx_type) {
|
||||||
|
vp10_fht16x16_c(in, out, stride, tx_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iht16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
|
void iht16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
|
||||||
int tx_type) {
|
int tx_type) {
|
||||||
vp9_iht16x16_256_add_c(in, dest, stride, tx_type);
|
vp10_iht16x16_256_add_c(in, dest, stride, tx_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
void idct16x16_10(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
vpx_highbd_idct16x16_256_add_c(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_12(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
vpx_highbd_idct16x16_256_add_c(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_10_ref(const tran_low_t *in, uint8_t *out, int stride,
|
void idct16x16_10_ref(const tran_low_t *in, uint8_t *out, int stride,
|
||||||
int /*tx_type*/) {
|
int tx_type) {
|
||||||
idct16x16_10(in, out, stride);
|
idct16x16_10(in, out, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_12_ref(const tran_low_t *in, uint8_t *out, int stride,
|
void idct16x16_12_ref(const tran_low_t *in, uint8_t *out, int stride,
|
||||||
int /*tx_type*/) {
|
int tx_type) {
|
||||||
idct16x16_12(in, out, stride);
|
idct16x16_12(in, out, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iht16x16_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
void iht16x16_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||||
vp9_highbd_iht16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 10);
|
vp10_highbd_iht16x16_256_add_c(in, out, stride, tx_type, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iht16x16_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
void iht16x16_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||||
vp9_highbd_iht16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 12);
|
vp10_highbd_iht16x16_256_add_c(in, out, stride, tx_type, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
void idct16x16_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_10_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
vpx_highbd_idct16x16_10_add_c(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_10_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
vpx_highbd_idct16x16_10_add_c(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_256_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_256_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_256_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
vpx_highbd_idct16x16_256_add_sse2(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_256_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_256_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_256_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
vpx_highbd_idct16x16_256_add_sse2(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_10_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
vpx_highbd_idct16x16_10_add_sse2(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_10_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
vpx_highbd_idct16x16_10_add_sse2(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
#endif // HAVE_SSE2
|
#endif // HAVE_SSE2
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
|
||||||
class Trans16x16TestBase {
|
class Trans16x16TestBase {
|
||||||
public:
|
public:
|
||||||
@@ -326,7 +331,7 @@ class Trans16x16TestBase {
|
|||||||
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]);
|
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
||||||
#endif
|
#endif
|
||||||
@@ -337,7 +342,7 @@ class Trans16x16TestBase {
|
|||||||
src[j] = rnd.Rand8();
|
src[j] = rnd.Rand8();
|
||||||
dst[j] = rnd.Rand8();
|
dst[j] = rnd.Rand8();
|
||||||
test_input_block[j] = src[j] - dst[j];
|
test_input_block[j] = src[j] - dst[j];
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
src16[j] = rnd.Rand16() & mask_;
|
src16[j] = rnd.Rand16() & mask_;
|
||||||
dst16[j] = rnd.Rand16() & mask_;
|
dst16[j] = rnd.Rand16() & mask_;
|
||||||
@@ -346,26 +351,28 @@ class Trans16x16TestBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block,
|
||||||
RunFwdTxfm(test_input_block, test_temp_block, pitch_));
|
test_temp_block, pitch_));
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
RunInvTxfm(test_temp_block, dst, pitch_));
|
||||||
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
const int32_t diff =
|
const int32_t diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
const int32_t diff = dst[j] - src[j];
|
const int32_t diff = dst[j] - src[j];
|
||||||
#endif
|
#endif
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
if (max_error < error) max_error = error;
|
if (max_error < error)
|
||||||
|
max_error = error;
|
||||||
total_error += error;
|
total_error += error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -386,9 +393,8 @@ class Trans16x16TestBase {
|
|||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
// Initialize a test block with input range [-mask_, mask_].
|
// Initialize a test block with input range [-mask_, mask_].
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
||||||
}
|
|
||||||
|
|
||||||
fwd_txfm_ref(input_block, output_ref_block, pitch_, tx_type_);
|
fwd_txfm_ref(input_block, output_ref_block, pitch_, tx_type_);
|
||||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_));
|
||||||
@@ -412,14 +418,16 @@ class Trans16x16TestBase {
|
|||||||
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
||||||
}
|
}
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_;
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
|
input_extreme_block[j] = mask_;
|
||||||
} else if (i == 1) {
|
} else if (i == 1) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_;
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
|
input_extreme_block[j] = -mask_;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
|
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block,
|
||||||
RunFwdTxfm(input_extreme_block, output_block, pitch_));
|
output_block, pitch_));
|
||||||
|
|
||||||
// The minimum quant value is 4.
|
// The minimum quant value is 4.
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
@@ -438,7 +446,7 @@ class Trans16x16TestBase {
|
|||||||
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]);
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]);
|
||||||
#endif
|
#endif
|
||||||
@@ -448,44 +456,45 @@ class Trans16x16TestBase {
|
|||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
||||||
}
|
}
|
||||||
if (i == 0) {
|
if (i == 0)
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_;
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
}
|
input_extreme_block[j] = mask_;
|
||||||
if (i == 1) {
|
if (i == 1)
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_;
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
}
|
input_extreme_block[j] = -mask_;
|
||||||
|
|
||||||
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
|
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
|
||||||
|
|
||||||
// clear reconstructed pixel buffers
|
// clear reconstructed pixel buffers
|
||||||
memset(dst, 0, kNumCoeffs * sizeof(uint8_t));
|
memset(dst, 0, kNumCoeffs * sizeof(uint8_t));
|
||||||
memset(ref, 0, kNumCoeffs * sizeof(uint8_t));
|
memset(ref, 0, kNumCoeffs * sizeof(uint8_t));
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
memset(dst16, 0, kNumCoeffs * sizeof(uint16_t));
|
memset(dst16, 0, kNumCoeffs * sizeof(uint16_t));
|
||||||
memset(ref16, 0, kNumCoeffs * sizeof(uint16_t));
|
memset(ref16, 0, kNumCoeffs * sizeof(uint16_t));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// quantization with maximum allowed step sizes
|
// quantization with maximum allowed step sizes
|
||||||
output_ref_block[0] = (output_ref_block[0] / dc_thred) * dc_thred;
|
output_ref_block[0] = (output_ref_block[0] / dc_thred) * dc_thred;
|
||||||
for (int j = 1; j < kNumCoeffs; ++j) {
|
for (int j = 1; j < kNumCoeffs; ++j)
|
||||||
output_ref_block[j] = (output_ref_block[j] / ac_thred) * ac_thred;
|
output_ref_block[j] = (output_ref_block[j] / ac_thred) * ac_thred;
|
||||||
}
|
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
inv_txfm_ref(output_ref_block, ref, pitch_, tx_type_);
|
inv_txfm_ref(output_ref_block, ref, pitch_, tx_type_);
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_));
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
inv_txfm_ref(output_ref_block, CAST_TO_BYTEPTR(ref16), pitch_,
|
inv_txfm_ref(output_ref_block, CONVERT_TO_BYTEPTR(ref16), pitch_,
|
||||||
tx_type_);
|
tx_type_);
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block,
|
||||||
RunInvTxfm(output_ref_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) EXPECT_EQ(ref[j], dst[j]);
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
EXPECT_EQ(ref[j], dst[j]);
|
||||||
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) EXPECT_EQ(ref16[j], dst16[j]);
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
|
EXPECT_EQ(ref16[j], dst16[j]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -498,10 +507,10 @@ class Trans16x16TestBase {
|
|||||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
double out_r[kNumCoeffs];
|
double out_r[kNumCoeffs];
|
||||||
@@ -512,38 +521,39 @@ class Trans16x16TestBase {
|
|||||||
src[j] = rnd.Rand8();
|
src[j] = rnd.Rand8();
|
||||||
dst[j] = rnd.Rand8();
|
dst[j] = rnd.Rand8();
|
||||||
in[j] = src[j] - dst[j];
|
in[j] = src[j] - dst[j];
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
src16[j] = rnd.Rand16() & mask_;
|
src16[j] = rnd.Rand16() & mask_;
|
||||||
dst16[j] = rnd.Rand16() & mask_;
|
dst16[j] = rnd.Rand16() & mask_;
|
||||||
in[j] = src16[j] - dst16[j];
|
in[j] = src16[j] - dst16[j];
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reference_16x16_dct_2d(in, out_r);
|
reference_16x16_dct_2d(in, out_r);
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
|
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
|
||||||
}
|
|
||||||
|
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), 16));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
16));
|
||||||
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
const uint32_t diff =
|
const uint32_t diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
const uint32_t diff = dst[j] - src[j];
|
const uint32_t diff = dst[j] - src[j];
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_GE(1u, error)
|
EXPECT_GE(1u, error)
|
||||||
<< "Error: 16x16 IDCT has error " << error << " at index " << j;
|
<< "Error: 16x16 IDCT has error " << error
|
||||||
|
<< " at index " << j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -552,14 +562,14 @@ class Trans16x16TestBase {
|
|||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
const int count_test_block = 10000;
|
const int count_test_block = 10000;
|
||||||
const int eob = 10;
|
const int eob = 10;
|
||||||
const int16_t *scan = vp9_default_scan_orders[TX_16X16].scan;
|
const int16_t *scan = vp10_default_scan_orders[TX_16X16].scan;
|
||||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]);
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]);
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
@@ -572,34 +582,35 @@ class Trans16x16TestBase {
|
|||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
dst[j] = 0;
|
dst[j] = 0;
|
||||||
ref[j] = 0;
|
ref[j] = 0;
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
dst16[j] = 0;
|
dst16[j] = 0;
|
||||||
ref16[j] = 0;
|
ref16[j] = 0;
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ref_txfm(coeff, ref, pitch_);
|
ref_txfm(coeff, ref, pitch_);
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||||
} else {
|
} else {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
ref_txfm(coeff, CAST_TO_BYTEPTR(ref16), pitch_);
|
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
||||||
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_));
|
pitch_));
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
const uint32_t diff =
|
const uint32_t diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j];
|
||||||
#else
|
#else
|
||||||
const uint32_t diff = dst[j] - ref[j];
|
const uint32_t diff = dst[j] - ref[j];
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_EQ(0u, error) << "Error: 16x16 IDCT Comparison has error "
|
EXPECT_EQ(0u, error)
|
||||||
<< error << " at index " << j;
|
<< "Error: 16x16 IDCT Comparison has error " << error
|
||||||
|
<< " at index " << j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -612,7 +623,8 @@ class Trans16x16TestBase {
|
|||||||
IhtFunc inv_txfm_ref;
|
IhtFunc inv_txfm_ref;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Trans16x16DCT : public Trans16x16TestBase,
|
class Trans16x16DCT
|
||||||
|
: public Trans16x16TestBase,
|
||||||
public ::testing::TestWithParam<Dct16x16Param> {
|
public ::testing::TestWithParam<Dct16x16Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~Trans16x16DCT() {}
|
virtual ~Trans16x16DCT() {}
|
||||||
@@ -626,11 +638,17 @@ class Trans16x16DCT : public Trans16x16TestBase,
|
|||||||
fwd_txfm_ref = fdct16x16_ref;
|
fwd_txfm_ref = fdct16x16_ref;
|
||||||
inv_txfm_ref = idct16x16_ref;
|
inv_txfm_ref = idct16x16_ref;
|
||||||
mask_ = (1 << bit_depth_) - 1;
|
mask_ = (1 << bit_depth_) - 1;
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
switch (bit_depth_) {
|
switch (bit_depth_) {
|
||||||
case VPX_BITS_10: inv_txfm_ref = idct16x16_10_ref; break;
|
case VPX_BITS_10:
|
||||||
case VPX_BITS_12: inv_txfm_ref = idct16x16_12_ref; break;
|
inv_txfm_ref = idct16x16_10_ref;
|
||||||
default: inv_txfm_ref = idct16x16_ref; break;
|
break;
|
||||||
|
case VPX_BITS_12:
|
||||||
|
inv_txfm_ref = idct16x16_12_ref;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
inv_txfm_ref = idct16x16_ref;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
inv_txfm_ref = idct16x16_ref;
|
inv_txfm_ref = idct16x16_ref;
|
||||||
@@ -650,11 +668,17 @@ class Trans16x16DCT : public Trans16x16TestBase,
|
|||||||
IdctFunc inv_txfm_;
|
IdctFunc inv_txfm_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(Trans16x16DCT, AccuracyCheck) { RunAccuracyCheck(); }
|
TEST_P(Trans16x16DCT, AccuracyCheck) {
|
||||||
|
RunAccuracyCheck();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(Trans16x16DCT, CoeffCheck) { RunCoeffCheck(); }
|
TEST_P(Trans16x16DCT, CoeffCheck) {
|
||||||
|
RunCoeffCheck();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(Trans16x16DCT, MemCheck) { RunMemCheck(); }
|
TEST_P(Trans16x16DCT, MemCheck) {
|
||||||
|
RunMemCheck();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(Trans16x16DCT, QuantCheck) {
|
TEST_P(Trans16x16DCT, QuantCheck) {
|
||||||
// Use maximally allowed quantization step sizes for DC and AC
|
// Use maximally allowed quantization step sizes for DC and AC
|
||||||
@@ -662,9 +686,12 @@ TEST_P(Trans16x16DCT, QuantCheck) {
|
|||||||
RunQuantCheck(1336, 1828);
|
RunQuantCheck(1336, 1828);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(Trans16x16DCT, InvAccuracyCheck) { RunInvAccuracyCheck(); }
|
TEST_P(Trans16x16DCT, InvAccuracyCheck) {
|
||||||
|
RunInvAccuracyCheck();
|
||||||
|
}
|
||||||
|
|
||||||
class Trans16x16HT : public Trans16x16TestBase,
|
class Trans16x16HT
|
||||||
|
: public Trans16x16TestBase,
|
||||||
public ::testing::TestWithParam<Ht16x16Param> {
|
public ::testing::TestWithParam<Ht16x16Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~Trans16x16HT() {}
|
virtual ~Trans16x16HT() {}
|
||||||
@@ -678,11 +705,17 @@ class Trans16x16HT : public Trans16x16TestBase,
|
|||||||
fwd_txfm_ref = fht16x16_ref;
|
fwd_txfm_ref = fht16x16_ref;
|
||||||
inv_txfm_ref = iht16x16_ref;
|
inv_txfm_ref = iht16x16_ref;
|
||||||
mask_ = (1 << bit_depth_) - 1;
|
mask_ = (1 << bit_depth_) - 1;
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
switch (bit_depth_) {
|
switch (bit_depth_) {
|
||||||
case VPX_BITS_10: inv_txfm_ref = iht16x16_10; break;
|
case VPX_BITS_10:
|
||||||
case VPX_BITS_12: inv_txfm_ref = iht16x16_12; break;
|
inv_txfm_ref = iht16x16_10;
|
||||||
default: inv_txfm_ref = iht16x16_ref; break;
|
break;
|
||||||
|
case VPX_BITS_12:
|
||||||
|
inv_txfm_ref = iht16x16_12;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
inv_txfm_ref = iht16x16_ref;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
inv_txfm_ref = iht16x16_ref;
|
inv_txfm_ref = iht16x16_ref;
|
||||||
@@ -702,11 +735,17 @@ class Trans16x16HT : public Trans16x16TestBase,
|
|||||||
IhtFunc inv_txfm_;
|
IhtFunc inv_txfm_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(Trans16x16HT, AccuracyCheck) { RunAccuracyCheck(); }
|
TEST_P(Trans16x16HT, AccuracyCheck) {
|
||||||
|
RunAccuracyCheck();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(Trans16x16HT, CoeffCheck) { RunCoeffCheck(); }
|
TEST_P(Trans16x16HT, CoeffCheck) {
|
||||||
|
RunCoeffCheck();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(Trans16x16HT, MemCheck) { RunMemCheck(); }
|
TEST_P(Trans16x16HT, MemCheck) {
|
||||||
|
RunMemCheck();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(Trans16x16HT, QuantCheck) {
|
TEST_P(Trans16x16HT, QuantCheck) {
|
||||||
// The encoder skips any non-DC intra prediction modes,
|
// The encoder skips any non-DC intra prediction modes,
|
||||||
@@ -714,7 +753,8 @@ TEST_P(Trans16x16HT, QuantCheck) {
|
|||||||
RunQuantCheck(429, 729);
|
RunQuantCheck(429, 729);
|
||||||
}
|
}
|
||||||
|
|
||||||
class InvTrans16x16DCT : public Trans16x16TestBase,
|
class InvTrans16x16DCT
|
||||||
|
: public Trans16x16TestBase,
|
||||||
public ::testing::TestWithParam<Idct16x16Param> {
|
public ::testing::TestWithParam<Idct16x16Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~InvTrans16x16DCT() {}
|
virtual ~InvTrans16x16DCT() {}
|
||||||
@@ -730,7 +770,7 @@ class InvTrans16x16DCT : public Trans16x16TestBase,
|
|||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void RunFwdTxfm(int16_t * /*in*/, tran_low_t * /*out*/, int /*stride*/) {}
|
void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) {}
|
||||||
void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) {
|
void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) {
|
||||||
inv_txfm_(out, dst, stride);
|
inv_txfm_(out, dst, stride);
|
||||||
}
|
}
|
||||||
@@ -744,9 +784,70 @@ TEST_P(InvTrans16x16DCT, CompareReference) {
|
|||||||
CompareInvReference(ref_txfm_, thresh_);
|
CompareInvReference(ref_txfm_, thresh_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PartialTrans16x16Test
|
||||||
|
: public ::testing::TestWithParam<
|
||||||
|
std::tr1::tuple<FdctFunc, vpx_bit_depth_t> > {
|
||||||
|
public:
|
||||||
|
virtual ~PartialTrans16x16Test() {}
|
||||||
|
virtual void SetUp() {
|
||||||
|
fwd_txfm_ = GET_PARAM(0);
|
||||||
|
bit_depth_ = GET_PARAM(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
vpx_bit_depth_t bit_depth_;
|
||||||
|
FdctFunc fwd_txfm_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(PartialTrans16x16Test, Extremes) {
|
||||||
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
const int16_t maxval =
|
||||||
|
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
|
||||||
|
#else
|
||||||
|
const int16_t maxval = 255;
|
||||||
|
#endif
|
||||||
|
const int minval = -maxval;
|
||||||
|
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
|
||||||
|
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
|
||||||
|
|
||||||
|
for (int i = 0; i < kNumCoeffs; ++i) input[i] = maxval;
|
||||||
|
output[0] = 0;
|
||||||
|
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 16));
|
||||||
|
EXPECT_EQ((maxval * kNumCoeffs) >> 1, output[0]);
|
||||||
|
|
||||||
|
for (int i = 0; i < kNumCoeffs; ++i) input[i] = minval;
|
||||||
|
output[0] = 0;
|
||||||
|
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 16));
|
||||||
|
EXPECT_EQ((minval * kNumCoeffs) >> 1, output[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(PartialTrans16x16Test, Random) {
|
||||||
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
const int16_t maxval =
|
||||||
|
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
|
||||||
|
#else
|
||||||
|
const int16_t maxval = 255;
|
||||||
|
#endif
|
||||||
|
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
|
||||||
|
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
|
||||||
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
|
|
||||||
|
int sum = 0;
|
||||||
|
for (int i = 0; i < kNumCoeffs; ++i) {
|
||||||
|
const int val = (i & 1) ? -rnd(maxval + 1) : rnd(maxval + 1);
|
||||||
|
input[i] = val;
|
||||||
|
sum += val;
|
||||||
|
}
|
||||||
|
output[0] = 0;
|
||||||
|
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 16));
|
||||||
|
EXPECT_EQ(sum >> 1, output[0]);
|
||||||
|
}
|
||||||
|
|
||||||
using std::tr1::make_tuple;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans16x16DCT,
|
C, Trans16x16DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
@@ -754,115 +855,138 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_12, 0, VPX_BITS_12),
|
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_12, 0, VPX_BITS_12),
|
||||||
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 0, VPX_BITS_8)));
|
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 0, VPX_BITS_8)));
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(C, Trans16x16DCT,
|
INSTANTIATE_TEST_CASE_P(
|
||||||
::testing::Values(make_tuple(&vpx_fdct16x16_c,
|
C, Trans16x16DCT,
|
||||||
&vpx_idct16x16_256_add_c,
|
::testing::Values(
|
||||||
0, VPX_BITS_8)));
|
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 0, VPX_BITS_8)));
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans16x16HT,
|
C, Trans16x16HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 0, VPX_BITS_10),
|
make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_10, 0, VPX_BITS_10),
|
||||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 1, VPX_BITS_10),
|
make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_10, 1, VPX_BITS_10),
|
||||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 2, VPX_BITS_10),
|
make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_10, 2, VPX_BITS_10),
|
||||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 3, VPX_BITS_10),
|
make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_10, 3, VPX_BITS_10),
|
||||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 0, VPX_BITS_12),
|
make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_12, 0, VPX_BITS_12),
|
||||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 1, VPX_BITS_12),
|
make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_12, 1, VPX_BITS_12),
|
||||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 2, VPX_BITS_12),
|
make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_12, 2, VPX_BITS_12),
|
||||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 3, VPX_BITS_12),
|
make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_12, 3, VPX_BITS_12),
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 0, VPX_BITS_8),
|
make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8),
|
make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8),
|
make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8)));
|
make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 3, VPX_BITS_8)));
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
C, PartialTrans16x16Test,
|
||||||
|
::testing::Values(make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_10),
|
||||||
|
make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_12)));
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans16x16HT,
|
C, Trans16x16HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 0, VPX_BITS_8),
|
make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8),
|
make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8),
|
make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8)));
|
make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 3, VPX_BITS_8)));
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
INSTANTIATE_TEST_CASE_P(C, PartialTrans16x16Test,
|
||||||
|
::testing::Values(make_tuple(&vpx_fdct16x16_1_c,
|
||||||
|
VPX_BITS_8)));
|
||||||
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
|
||||||
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_NEON_ASM && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, Trans16x16DCT,
|
NEON, Trans16x16DCT,
|
||||||
::testing::Values(make_tuple(&vpx_fdct16x16_neon,
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_fdct16x16_c,
|
||||||
&vpx_idct16x16_256_add_neon, 0, VPX_BITS_8)));
|
&vpx_idct16x16_256_add_neon, 0, VPX_BITS_8)));
|
||||||
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
#endif
|
||||||
|
|
||||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans16x16DCT,
|
SSE2, Trans16x16DCT,
|
||||||
::testing::Values(make_tuple(&vpx_fdct16x16_sse2,
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_fdct16x16_sse2,
|
||||||
&vpx_idct16x16_256_add_sse2, 0, VPX_BITS_8)));
|
&vpx_idct16x16_256_add_sse2, 0, VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans16x16HT,
|
SSE2, Trans16x16HT,
|
||||||
::testing::Values(make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
|
::testing::Values(
|
||||||
0, VPX_BITS_8),
|
make_tuple(&vp10_fht16x16_sse2, &vp10_iht16x16_256_add_sse2, 0,
|
||||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
|
VPX_BITS_8),
|
||||||
1, VPX_BITS_8),
|
make_tuple(&vp10_fht16x16_sse2, &vp10_iht16x16_256_add_sse2, 1,
|
||||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
|
VPX_BITS_8),
|
||||||
2, VPX_BITS_8),
|
make_tuple(&vp10_fht16x16_sse2, &vp10_iht16x16_256_add_sse2, 2,
|
||||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
|
VPX_BITS_8),
|
||||||
3, VPX_BITS_8)));
|
make_tuple(&vp10_fht16x16_sse2, &vp10_iht16x16_256_add_sse2, 3,
|
||||||
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
VPX_BITS_8)));
|
||||||
|
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
|
||||||
|
::testing::Values(make_tuple(&vpx_fdct16x16_1_sse2,
|
||||||
|
VPX_BITS_8)));
|
||||||
|
#endif // HAVE_SSE2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans16x16DCT,
|
SSE2, Trans16x16DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_10, 0, VPX_BITS_10),
|
make_tuple(&vpx_highbd_fdct16x16_sse2,
|
||||||
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_256_add_10_sse2, 0,
|
&idct16x16_10, 0, VPX_BITS_10),
|
||||||
VPX_BITS_10),
|
make_tuple(&vpx_highbd_fdct16x16_c,
|
||||||
make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_12, 0, VPX_BITS_12),
|
&idct16x16_256_add_10_sse2, 0, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_256_add_12_sse2, 0,
|
make_tuple(&vpx_highbd_fdct16x16_sse2,
|
||||||
VPX_BITS_12),
|
&idct16x16_12, 0, VPX_BITS_12),
|
||||||
make_tuple(&vpx_fdct16x16_sse2, &vpx_idct16x16_256_add_c, 0,
|
make_tuple(&vpx_highbd_fdct16x16_c,
|
||||||
VPX_BITS_8)));
|
&idct16x16_256_add_12_sse2, 0, VPX_BITS_12),
|
||||||
|
make_tuple(&vpx_fdct16x16_sse2,
|
||||||
|
&vpx_idct16x16_256_add_c, 0, VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans16x16HT,
|
SSE2, Trans16x16HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 0, VPX_BITS_8),
|
make_tuple(&vp10_fht16x16_sse2,
|
||||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8),
|
&vp10_iht16x16_256_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8),
|
make_tuple(&vp10_fht16x16_sse2,
|
||||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 3,
|
&vp10_iht16x16_256_add_c, 1, VPX_BITS_8),
|
||||||
|
make_tuple(&vp10_fht16x16_sse2,
|
||||||
|
&vp10_iht16x16_256_add_c, 2, VPX_BITS_8),
|
||||||
|
make_tuple(&vp10_fht16x16_sse2, &vp10_iht16x16_256_add_c, 3,
|
||||||
VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
// Optimizations take effect at a threshold of 3155, so we use a value close to
|
// Optimizations take effect at a threshold of 3155, so we use a value close to
|
||||||
// that to test both branches.
|
// that to test both branches.
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, InvTrans16x16DCT,
|
SSE2, InvTrans16x16DCT,
|
||||||
::testing::Values(make_tuple(&idct16x16_10_add_10_c,
|
::testing::Values(
|
||||||
|
make_tuple(&idct16x16_10_add_10_c,
|
||||||
&idct16x16_10_add_10_sse2, 3167, VPX_BITS_10),
|
&idct16x16_10_add_10_sse2, 3167, VPX_BITS_10),
|
||||||
make_tuple(&idct16x16_10, &idct16x16_256_add_10_sse2,
|
make_tuple(&idct16x16_10,
|
||||||
3167, VPX_BITS_10),
|
&idct16x16_256_add_10_sse2, 3167, VPX_BITS_10),
|
||||||
make_tuple(&idct16x16_10_add_12_c,
|
make_tuple(&idct16x16_10_add_12_c,
|
||||||
&idct16x16_10_add_12_sse2, 3167, VPX_BITS_12),
|
&idct16x16_10_add_12_sse2, 3167, VPX_BITS_12),
|
||||||
make_tuple(&idct16x16_12, &idct16x16_256_add_12_sse2,
|
make_tuple(&idct16x16_12,
|
||||||
3167, VPX_BITS_12)));
|
&idct16x16_256_add_12_sse2, 3167, VPX_BITS_12)));
|
||||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
|
||||||
|
::testing::Values(make_tuple(&vpx_fdct16x16_1_sse2,
|
||||||
|
VPX_BITS_8)));
|
||||||
|
#endif // HAVE_SSE2 && CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(MSA, Trans16x16DCT,
|
INSTANTIATE_TEST_CASE_P(
|
||||||
::testing::Values(make_tuple(&vpx_fdct16x16_msa,
|
MSA, Trans16x16DCT,
|
||||||
&vpx_idct16x16_256_add_msa,
|
::testing::Values(
|
||||||
0, VPX_BITS_8)));
|
make_tuple(&vpx_fdct16x16_msa,
|
||||||
|
&vpx_idct16x16_256_add_msa, 0, VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
MSA, Trans16x16HT,
|
MSA, Trans16x16HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 0, VPX_BITS_8),
|
make_tuple(&vp10_fht16x16_msa,
|
||||||
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 1, VPX_BITS_8),
|
&vp10_iht16x16_256_add_msa, 0, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 2, VPX_BITS_8),
|
make_tuple(&vp10_fht16x16_msa,
|
||||||
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 3,
|
&vp10_iht16x16_256_add_msa, 1, VPX_BITS_8),
|
||||||
|
make_tuple(&vp10_fht16x16_msa,
|
||||||
|
&vp10_iht16x16_256_add_msa, 2, VPX_BITS_8),
|
||||||
|
make_tuple(&vp10_fht16x16_msa,
|
||||||
|
&vp10_iht16x16_256_add_msa, 3, VPX_BITS_8)));
|
||||||
|
INSTANTIATE_TEST_CASE_P(MSA, PartialTrans16x16Test,
|
||||||
|
::testing::Values(make_tuple(&vpx_fdct16x16_1_msa,
|
||||||
VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
INSTANTIATE_TEST_CASE_P(VSX, Trans16x16DCT,
|
|
||||||
::testing::Values(make_tuple(&vpx_fdct16x16_c,
|
|
||||||
&vpx_idct16x16_256_add_vsx,
|
|
||||||
0, VPX_BITS_8)));
|
|
||||||
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -14,14 +14,14 @@
|
|||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vp9_rtcd.h"
|
#include "./vp10_rtcd.h"
|
||||||
#include "./vpx_config.h"
|
#include "./vpx_config.h"
|
||||||
#include "./vpx_dsp_rtcd.h"
|
#include "./vpx_dsp_rtcd.h"
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
#include "vp9/common/vp9_entropy.h"
|
#include "vp10/common/entropy.h"
|
||||||
#include "vpx/vpx_codec.h"
|
#include "vpx/vpx_codec.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
#include "vpx_ports/mem.h"
|
#include "vpx_ports/mem.h"
|
||||||
@@ -37,10 +37,10 @@ void reference_32x32_dct_1d(const double in[32], double out[32]) {
|
|||||||
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
||||||
for (int k = 0; k < 32; k++) {
|
for (int k = 0; k < 32; k++) {
|
||||||
out[k] = 0.0;
|
out[k] = 0.0;
|
||||||
for (int n = 0; n < 32; n++) {
|
for (int n = 0; n < 32; n++)
|
||||||
out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 64.0);
|
out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 64.0);
|
||||||
}
|
if (k == 0)
|
||||||
if (k == 0) out[k] = out[k] * kInvSqrt2;
|
out[k] = out[k] * kInvSqrt2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,17 +49,21 @@ void reference_32x32_dct_2d(const int16_t input[kNumCoeffs],
|
|||||||
// First transform columns
|
// First transform columns
|
||||||
for (int i = 0; i < 32; ++i) {
|
for (int i = 0; i < 32; ++i) {
|
||||||
double temp_in[32], temp_out[32];
|
double temp_in[32], temp_out[32];
|
||||||
for (int j = 0; j < 32; ++j) temp_in[j] = input[j * 32 + i];
|
for (int j = 0; j < 32; ++j)
|
||||||
|
temp_in[j] = input[j*32 + i];
|
||||||
reference_32x32_dct_1d(temp_in, temp_out);
|
reference_32x32_dct_1d(temp_in, temp_out);
|
||||||
for (int j = 0; j < 32; ++j) output[j * 32 + i] = temp_out[j];
|
for (int j = 0; j < 32; ++j)
|
||||||
|
output[j * 32 + i] = temp_out[j];
|
||||||
}
|
}
|
||||||
// Then transform rows
|
// Then transform rows
|
||||||
for (int i = 0; i < 32; ++i) {
|
for (int i = 0; i < 32; ++i) {
|
||||||
double temp_in[32], temp_out[32];
|
double temp_in[32], temp_out[32];
|
||||||
for (int j = 0; j < 32; ++j) temp_in[j] = output[j + i * 32];
|
for (int j = 0; j < 32; ++j)
|
||||||
|
temp_in[j] = output[j + i*32];
|
||||||
reference_32x32_dct_1d(temp_in, temp_out);
|
reference_32x32_dct_1d(temp_in, temp_out);
|
||||||
// Scale by some magic number
|
// Scale by some magic number
|
||||||
for (int j = 0; j < 32; ++j) output[j + i * 32] = temp_out[j] / 4;
|
for (int j = 0; j < 32; ++j)
|
||||||
|
output[j + i * 32] = temp_out[j] / 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,15 +73,15 @@ typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride);
|
|||||||
typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t>
|
typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t>
|
||||||
Trans32x32Param;
|
Trans32x32Param;
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
void idct32x32_10(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct32x32_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct32x32_1024_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
vpx_highbd_idct32x32_1024_add_c(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct32x32_12(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct32x32_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct32x32_1024_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
vpx_highbd_idct32x32_1024_add_c(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
|
||||||
class Trans32x32Test : public ::testing::TestWithParam<Trans32x32Param> {
|
class Trans32x32Test : public ::testing::TestWithParam<Trans32x32Param> {
|
||||||
public:
|
public:
|
||||||
@@ -110,7 +114,7 @@ TEST_P(Trans32x32Test, AccuracyCheck) {
|
|||||||
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]);
|
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
||||||
#endif
|
#endif
|
||||||
@@ -122,7 +126,7 @@ TEST_P(Trans32x32Test, AccuracyCheck) {
|
|||||||
src[j] = rnd.Rand8();
|
src[j] = rnd.Rand8();
|
||||||
dst[j] = rnd.Rand8();
|
dst[j] = rnd.Rand8();
|
||||||
test_input_block[j] = src[j] - dst[j];
|
test_input_block[j] = src[j] - dst[j];
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
src16[j] = rnd.Rand16() & mask_;
|
src16[j] = rnd.Rand16() & mask_;
|
||||||
dst16[j] = rnd.Rand16() & mask_;
|
dst16[j] = rnd.Rand16() & mask_;
|
||||||
@@ -134,22 +138,23 @@ TEST_P(Trans32x32Test, AccuracyCheck) {
|
|||||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(test_input_block, test_temp_block, 32));
|
ASM_REGISTER_STATE_CHECK(fwd_txfm_(test_input_block, test_temp_block, 32));
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(test_temp_block, dst, 32));
|
ASM_REGISTER_STATE_CHECK(inv_txfm_(test_temp_block, dst, 32));
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(inv_txfm_(test_temp_block,
|
||||||
inv_txfm_(test_temp_block, CAST_TO_BYTEPTR(dst16), 32));
|
CONVERT_TO_BYTEPTR(dst16), 32));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
const int32_t diff =
|
const int32_t diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
const int32_t diff = dst[j] - src[j];
|
const int32_t diff = dst[j] - src[j];
|
||||||
#endif
|
#endif
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
if (max_error < error) max_error = error;
|
if (max_error < error)
|
||||||
|
max_error = error;
|
||||||
total_error += error;
|
total_error += error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,9 +180,8 @@ TEST_P(Trans32x32Test, CoeffCheck) {
|
|||||||
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
||||||
}
|
|
||||||
|
|
||||||
const int stride = 32;
|
const int stride = 32;
|
||||||
vpx_fdct32x32_c(input_block, output_ref_block, stride);
|
vpx_fdct32x32_c(input_block, output_ref_block, stride);
|
||||||
@@ -209,9 +213,11 @@ TEST_P(Trans32x32Test, MemCheck) {
|
|||||||
input_extreme_block[j] = rnd.Rand8() & 1 ? mask_ : -mask_;
|
input_extreme_block[j] = rnd.Rand8() & 1 ? mask_ : -mask_;
|
||||||
}
|
}
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_;
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
|
input_extreme_block[j] = mask_;
|
||||||
} else if (i == 1) {
|
} else if (i == 1) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_;
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
|
input_extreme_block[j] = -mask_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int stride = 32;
|
const int stride = 32;
|
||||||
@@ -244,7 +250,7 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
|
|||||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
||||||
#endif
|
#endif
|
||||||
@@ -258,7 +264,7 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
|
|||||||
src[j] = rnd.Rand8();
|
src[j] = rnd.Rand8();
|
||||||
dst[j] = rnd.Rand8();
|
dst[j] = rnd.Rand8();
|
||||||
in[j] = src[j] - dst[j];
|
in[j] = src[j] - dst[j];
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
src16[j] = rnd.Rand16() & mask_;
|
src16[j] = rnd.Rand16() & mask_;
|
||||||
dst16[j] = rnd.Rand16() & mask_;
|
dst16[j] = rnd.Rand16() & mask_;
|
||||||
@@ -268,71 +274,151 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reference_32x32_dct_2d(in, out_r);
|
reference_32x32_dct_2d(in, out_r);
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
|
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
|
||||||
}
|
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, dst, 32));
|
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, dst, 32));
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, CAST_TO_BYTEPTR(dst16), 32));
|
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, CONVERT_TO_BYTEPTR(dst16), 32));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
const int diff =
|
const int diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
const int diff = dst[j] - src[j];
|
const int diff = dst[j] - src[j];
|
||||||
#endif
|
#endif
|
||||||
const int error = diff * diff;
|
const int error = diff * diff;
|
||||||
EXPECT_GE(1, error) << "Error: 32x32 IDCT has error " << error
|
EXPECT_GE(1, error)
|
||||||
|
<< "Error: 32x32 IDCT has error " << error
|
||||||
<< " at index " << j;
|
<< " at index " << j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PartialTrans32x32Test
|
||||||
|
: public ::testing::TestWithParam<
|
||||||
|
std::tr1::tuple<FwdTxfmFunc, vpx_bit_depth_t> > {
|
||||||
|
public:
|
||||||
|
virtual ~PartialTrans32x32Test() {}
|
||||||
|
virtual void SetUp() {
|
||||||
|
fwd_txfm_ = GET_PARAM(0);
|
||||||
|
bit_depth_ = GET_PARAM(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
vpx_bit_depth_t bit_depth_;
|
||||||
|
FwdTxfmFunc fwd_txfm_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(PartialTrans32x32Test, Extremes) {
|
||||||
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
const int16_t maxval =
|
||||||
|
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
|
||||||
|
#else
|
||||||
|
const int16_t maxval = 255;
|
||||||
|
#endif
|
||||||
|
const int minval = -maxval;
|
||||||
|
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
|
||||||
|
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
|
||||||
|
|
||||||
|
for (int i = 0; i < kNumCoeffs; ++i) input[i] = maxval;
|
||||||
|
output[0] = 0;
|
||||||
|
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 32));
|
||||||
|
EXPECT_EQ((maxval * kNumCoeffs) >> 3, output[0]);
|
||||||
|
|
||||||
|
for (int i = 0; i < kNumCoeffs; ++i) input[i] = minval;
|
||||||
|
output[0] = 0;
|
||||||
|
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 32));
|
||||||
|
EXPECT_EQ((minval * kNumCoeffs) >> 3, output[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(PartialTrans32x32Test, Random) {
|
||||||
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
const int16_t maxval =
|
||||||
|
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
|
||||||
|
#else
|
||||||
|
const int16_t maxval = 255;
|
||||||
|
#endif
|
||||||
|
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
|
||||||
|
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
|
||||||
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
|
|
||||||
|
int sum = 0;
|
||||||
|
for (int i = 0; i < kNumCoeffs; ++i) {
|
||||||
|
const int val = (i & 1) ? -rnd(maxval + 1) : rnd(maxval + 1);
|
||||||
|
input[i] = val;
|
||||||
|
sum += val;
|
||||||
|
}
|
||||||
|
output[0] = 0;
|
||||||
|
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 32));
|
||||||
|
EXPECT_EQ(sum >> 3, output[0]);
|
||||||
|
}
|
||||||
|
|
||||||
using std::tr1::make_tuple;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans32x32Test,
|
C, Trans32x32Test,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_highbd_fdct32x32_c, &idct32x32_10, 0, VPX_BITS_10),
|
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||||
make_tuple(&vpx_highbd_fdct32x32_rd_c, &idct32x32_10, 1, VPX_BITS_10),
|
&idct32x32_10, 0, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct32x32_c, &idct32x32_12, 0, VPX_BITS_12),
|
make_tuple(&vpx_highbd_fdct32x32_rd_c,
|
||||||
make_tuple(&vpx_highbd_fdct32x32_rd_c, &idct32x32_12, 1, VPX_BITS_12),
|
&idct32x32_10, 1, VPX_BITS_10),
|
||||||
make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 0, VPX_BITS_8),
|
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||||
make_tuple(&vpx_fdct32x32_rd_c, &vpx_idct32x32_1024_add_c, 1,
|
&idct32x32_12, 0, VPX_BITS_12),
|
||||||
VPX_BITS_8)));
|
make_tuple(&vpx_highbd_fdct32x32_rd_c,
|
||||||
|
&idct32x32_12, 1, VPX_BITS_12),
|
||||||
|
make_tuple(&vpx_fdct32x32_c,
|
||||||
|
&vpx_idct32x32_1024_add_c, 0, VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_fdct32x32_rd_c,
|
||||||
|
&vpx_idct32x32_1024_add_c, 1, VPX_BITS_8)));
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
C, PartialTrans32x32Test,
|
||||||
|
::testing::Values(make_tuple(&vpx_highbd_fdct32x32_1_c, VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_highbd_fdct32x32_1_c, VPX_BITS_10),
|
||||||
|
make_tuple(&vpx_highbd_fdct32x32_1_c, VPX_BITS_12)));
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans32x32Test,
|
C, Trans32x32Test,
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 0,
|
::testing::Values(
|
||||||
VPX_BITS_8),
|
make_tuple(&vpx_fdct32x32_c,
|
||||||
make_tuple(&vpx_fdct32x32_rd_c, &vpx_idct32x32_1024_add_c,
|
&vpx_idct32x32_1024_add_c, 0, VPX_BITS_8),
|
||||||
1, VPX_BITS_8)));
|
make_tuple(&vpx_fdct32x32_rd_c,
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
&vpx_idct32x32_1024_add_c, 1, VPX_BITS_8)));
|
||||||
|
INSTANTIATE_TEST_CASE_P(C, PartialTrans32x32Test,
|
||||||
|
::testing::Values(make_tuple(&vpx_fdct32x32_1_c,
|
||||||
|
VPX_BITS_8)));
|
||||||
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
|
||||||
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_NEON && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, Trans32x32Test,
|
NEON, Trans32x32Test,
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_neon,
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_fdct32x32_c,
|
||||||
&vpx_idct32x32_1024_add_neon, 0, VPX_BITS_8),
|
&vpx_idct32x32_1024_add_neon, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_neon,
|
make_tuple(&vpx_fdct32x32_rd_c,
|
||||||
&vpx_idct32x32_1024_add_neon, 1, VPX_BITS_8)));
|
&vpx_idct32x32_1024_add_neon, 1, VPX_BITS_8)));
|
||||||
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_NEON && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans32x32Test,
|
SSE2, Trans32x32Test,
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_sse2,
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_fdct32x32_sse2,
|
||||||
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_sse2,
|
make_tuple(&vpx_fdct32x32_rd_sse2,
|
||||||
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
|
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
|
||||||
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans32x32Test,
|
||||||
|
::testing::Values(make_tuple(&vpx_fdct32x32_1_sse2,
|
||||||
|
VPX_BITS_8)));
|
||||||
|
#endif // HAVE_SSE2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans32x32Test,
|
SSE2, Trans32x32Test,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
@@ -346,32 +432,31 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
VPX_BITS_8),
|
VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_sse2, &vpx_idct32x32_1024_add_c, 1,
|
make_tuple(&vpx_fdct32x32_rd_sse2, &vpx_idct32x32_1024_add_c, 1,
|
||||||
VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans32x32Test,
|
||||||
|
::testing::Values(make_tuple(&vpx_fdct32x32_1_sse2,
|
||||||
|
VPX_BITS_8)));
|
||||||
|
#endif // HAVE_SSE2 && CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_AVX2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
AVX2, Trans32x32Test,
|
AVX2, Trans32x32Test,
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_avx2,
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_fdct32x32_avx2,
|
||||||
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_avx2,
|
make_tuple(&vpx_fdct32x32_rd_avx2,
|
||||||
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
|
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
|
||||||
#endif // HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_AVX2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
MSA, Trans32x32Test,
|
MSA, Trans32x32Test,
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_msa,
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_fdct32x32_msa,
|
||||||
&vpx_idct32x32_1024_add_msa, 0, VPX_BITS_8),
|
&vpx_idct32x32_1024_add_msa, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_msa,
|
make_tuple(&vpx_fdct32x32_rd_msa,
|
||||||
&vpx_idct32x32_1024_add_msa, 1, VPX_BITS_8)));
|
&vpx_idct32x32_1024_add_msa, 1, VPX_BITS_8)));
|
||||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
INSTANTIATE_TEST_CASE_P(MSA, PartialTrans32x32Test,
|
||||||
|
::testing::Values(make_tuple(&vpx_fdct32x32_1_msa,
|
||||||
#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(
|
#endif // HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
VSX, Trans32x32Test,
|
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_vsx,
|
|
||||||
0, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct32x32_rd_c,
|
|
||||||
&vpx_idct32x32_1024_add_vsx, 1, VPX_BITS_8)));
|
|
||||||
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -1,169 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
#include "test/acm_random.h"
|
|
||||||
#include "test/buffer.h"
|
|
||||||
#include "test/clear_system_state.h"
|
|
||||||
#include "test/register_state_check.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
#include "vpx/vpx_codec.h"
|
|
||||||
#include "vpx/vpx_integer.h"
|
|
||||||
#include "vpx_dsp/vpx_dsp_common.h"
|
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
|
||||||
using libvpx_test::Buffer;
|
|
||||||
using std::tr1::tuple;
|
|
||||||
using std::tr1::make_tuple;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
typedef void (*PartialFdctFunc)(const int16_t *in, tran_low_t *out, int stride);
|
|
||||||
|
|
||||||
typedef tuple<PartialFdctFunc, int /* size */, vpx_bit_depth_t>
|
|
||||||
PartialFdctParam;
|
|
||||||
|
|
||||||
tran_low_t partial_fdct_ref(const Buffer<int16_t> &in, int size) {
|
|
||||||
int64_t sum = 0;
|
|
||||||
for (int y = 0; y < size; ++y) {
|
|
||||||
for (int x = 0; x < size; ++x) {
|
|
||||||
sum += in.TopLeftPixel()[y * in.stride() + x];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (size) {
|
|
||||||
case 4: sum *= 2; break;
|
|
||||||
case 8: /*sum = sum;*/ break;
|
|
||||||
case 16: sum >>= 1; break;
|
|
||||||
case 32: sum >>= 3; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return static_cast<tran_low_t>(sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
class PartialFdctTest : public ::testing::TestWithParam<PartialFdctParam> {
|
|
||||||
public:
|
|
||||||
PartialFdctTest() {
|
|
||||||
fwd_txfm_ = GET_PARAM(0);
|
|
||||||
size_ = GET_PARAM(1);
|
|
||||||
bit_depth_ = GET_PARAM(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void RunTest() {
|
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
||||||
const int16_t maxvalue =
|
|
||||||
clip_pixel_highbd(std::numeric_limits<int16_t>::max(), bit_depth_);
|
|
||||||
const int16_t minvalue = -maxvalue;
|
|
||||||
Buffer<int16_t> input_block =
|
|
||||||
Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16);
|
|
||||||
ASSERT_TRUE(input_block.Init());
|
|
||||||
Buffer<tran_low_t> output_block = Buffer<tran_low_t>(size_, size_, 0, 16);
|
|
||||||
ASSERT_TRUE(output_block.Init());
|
|
||||||
|
|
||||||
for (int i = 0; i < 100; ++i) {
|
|
||||||
if (i == 0) {
|
|
||||||
input_block.Set(maxvalue);
|
|
||||||
} else if (i == 1) {
|
|
||||||
input_block.Set(minvalue);
|
|
||||||
} else {
|
|
||||||
input_block.Set(&rnd, minvalue, maxvalue);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input_block.TopLeftPixel(),
|
|
||||||
output_block.TopLeftPixel(),
|
|
||||||
input_block.stride()));
|
|
||||||
|
|
||||||
EXPECT_EQ(partial_fdct_ref(input_block, size_),
|
|
||||||
output_block.TopLeftPixel()[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PartialFdctFunc fwd_txfm_;
|
|
||||||
vpx_bit_depth_t bit_depth_;
|
|
||||||
int size_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(PartialFdctTest, PartialFdctTest) { RunTest(); }
|
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
C, PartialFdctTest,
|
|
||||||
::testing::Values(make_tuple(&vpx_highbd_fdct32x32_1_c, 32, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_fdct32x32_1_c, 32, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_fdct32x32_1_c, 32, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_fdct16x16_1_c, 16, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_fdct16x16_1_c, 16, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_fdct16x16_1_c, 16, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_fdct8x8_1_c, 8, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_fdct8x8_1_c, 8, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_fdct8x8_1_c, 8, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct4x4_1_c, 4, VPX_BITS_8)));
|
|
||||||
#else
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
C, PartialFdctTest,
|
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_c, 32, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct16x16_1_c, 16, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct8x8_1_c, 8, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct4x4_1_c, 4, VPX_BITS_8)));
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
|
|
||||||
#if HAVE_SSE2
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE2, PartialFdctTest,
|
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_sse2, 32, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct16x16_1_sse2, 16, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct8x8_1_sse2, 8, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct4x4_1_sse2, 4, VPX_BITS_8)));
|
|
||||||
#endif // HAVE_SSE2
|
|
||||||
|
|
||||||
#if HAVE_NEON
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
NEON, PartialFdctTest,
|
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_neon, 32, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct16x16_1_neon, 16, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_8)));
|
|
||||||
#else
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
NEON, PartialFdctTest,
|
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_neon, 32, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct16x16_1_neon, 16, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_8)));
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
#endif // HAVE_NEON
|
|
||||||
|
|
||||||
#if HAVE_MSA
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
INSTANTIATE_TEST_CASE_P(MSA, PartialFdctTest,
|
|
||||||
::testing::Values(make_tuple(&vpx_fdct8x8_1_msa, 8,
|
|
||||||
VPX_BITS_8)));
|
|
||||||
#else // !CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MSA, PartialFdctTest,
|
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_msa, 32, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct16x16_1_msa, 16, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct8x8_1_msa, 8, VPX_BITS_8)));
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
#endif // HAVE_MSA
|
|
||||||
} // namespace
|
|
||||||
737
test/dct_test.cc
737
test/dct_test.cc
@@ -1,737 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "./vp9_rtcd.h"
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
#include "test/acm_random.h"
|
|
||||||
#include "test/buffer.h"
|
|
||||||
#include "test/clear_system_state.h"
|
|
||||||
#include "test/register_state_check.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
#include "vp9/common/vp9_entropy.h"
|
|
||||||
#include "vpx/vpx_codec.h"
|
|
||||||
#include "vpx/vpx_integer.h"
|
|
||||||
#include "vpx_ports/mem.h"
|
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
|
||||||
using libvpx_test::Buffer;
|
|
||||||
using std::tr1::tuple;
|
|
||||||
using std::tr1::make_tuple;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride);
|
|
||||||
typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride);
|
|
||||||
typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride,
|
|
||||||
int tx_type);
|
|
||||||
typedef void (*FhtFuncRef)(const Buffer<int16_t> &in, Buffer<tran_low_t> *out,
|
|
||||||
int size, int tx_type);
|
|
||||||
typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride,
|
|
||||||
int tx_type);
|
|
||||||
|
|
||||||
/* forward transform, inverse transform, size, transform type, bit depth */
|
|
||||||
typedef tuple<FdctFunc, IdctFunc, int, int, vpx_bit_depth_t> DctParam;
|
|
||||||
typedef tuple<FhtFunc, IhtFunc, int, int, vpx_bit_depth_t> HtParam;
|
|
||||||
|
|
||||||
void fdct_ref(const Buffer<int16_t> &in, Buffer<tran_low_t> *out, int size,
|
|
||||||
int /*tx_type*/) {
|
|
||||||
const int16_t *i = in.TopLeftPixel();
|
|
||||||
const int i_stride = in.stride();
|
|
||||||
tran_low_t *o = out->TopLeftPixel();
|
|
||||||
if (size == 4) {
|
|
||||||
vpx_fdct4x4_c(i, o, i_stride);
|
|
||||||
} else if (size == 8) {
|
|
||||||
vpx_fdct8x8_c(i, o, i_stride);
|
|
||||||
} else if (size == 16) {
|
|
||||||
vpx_fdct16x16_c(i, o, i_stride);
|
|
||||||
} else if (size == 32) {
|
|
||||||
vpx_fdct32x32_c(i, o, i_stride);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void fht_ref(const Buffer<int16_t> &in, Buffer<tran_low_t> *out, int size,
|
|
||||||
int tx_type) {
|
|
||||||
const int16_t *i = in.TopLeftPixel();
|
|
||||||
const int i_stride = in.stride();
|
|
||||||
tran_low_t *o = out->TopLeftPixel();
|
|
||||||
if (size == 4) {
|
|
||||||
vp9_fht4x4_c(i, o, i_stride, tx_type);
|
|
||||||
} else if (size == 8) {
|
|
||||||
vp9_fht8x8_c(i, o, i_stride, tx_type);
|
|
||||||
} else if (size == 16) {
|
|
||||||
vp9_fht16x16_c(i, o, i_stride, tx_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void fwht_ref(const Buffer<int16_t> &in, Buffer<tran_low_t> *out, int size,
|
|
||||||
int /*tx_type*/) {
|
|
||||||
ASSERT_EQ(size, 4);
|
|
||||||
vp9_fwht4x4_c(in.TopLeftPixel(), out->TopLeftPixel(), in.stride());
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
#define idctNxN(n, coeffs, bitdepth) \
|
|
||||||
void idct##n##x##n##_##bitdepth(const tran_low_t *in, uint8_t *out, \
|
|
||||||
int stride) { \
|
|
||||||
vpx_highbd_idct##n##x##n##_##coeffs##_add_c(in, CAST_TO_SHORTPTR(out), \
|
|
||||||
stride, bitdepth); \
|
|
||||||
}
|
|
||||||
|
|
||||||
idctNxN(4, 16, 10);
|
|
||||||
idctNxN(4, 16, 12);
|
|
||||||
idctNxN(8, 64, 10);
|
|
||||||
idctNxN(8, 64, 12);
|
|
||||||
idctNxN(16, 256, 10);
|
|
||||||
idctNxN(16, 256, 12);
|
|
||||||
idctNxN(32, 1024, 10);
|
|
||||||
idctNxN(32, 1024, 12);
|
|
||||||
|
|
||||||
#define ihtNxN(n, coeffs, bitdepth) \
|
|
||||||
void iht##n##x##n##_##bitdepth(const tran_low_t *in, uint8_t *out, \
|
|
||||||
int stride, int tx_type) { \
|
|
||||||
vp9_highbd_iht##n##x##n##_##coeffs##_add_c(in, CAST_TO_SHORTPTR(out), \
|
|
||||||
stride, tx_type, bitdepth); \
|
|
||||||
}
|
|
||||||
|
|
||||||
ihtNxN(4, 16, 10);
|
|
||||||
ihtNxN(4, 16, 12);
|
|
||||||
ihtNxN(8, 64, 10);
|
|
||||||
ihtNxN(8, 64, 12);
|
|
||||||
ihtNxN(16, 256, 10);
|
|
||||||
// ihtNxN(16, 256, 12);
|
|
||||||
|
|
||||||
void iwht4x4_10(const tran_low_t *in, uint8_t *out, int stride) {
|
|
||||||
vpx_highbd_iwht4x4_16_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void iwht4x4_12(const tran_low_t *in, uint8_t *out, int stride) {
|
|
||||||
vpx_highbd_iwht4x4_16_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
|
||||||
}
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
|
|
||||||
class TransTestBase {
|
|
||||||
public:
|
|
||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void RunFwdTxfm(const Buffer<int16_t> &in,
|
|
||||||
Buffer<tran_low_t> *out) = 0;
|
|
||||||
|
|
||||||
virtual void RunInvTxfm(const Buffer<tran_low_t> &in, uint8_t *out) = 0;
|
|
||||||
|
|
||||||
void RunAccuracyCheck(int limit) {
|
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
||||||
Buffer<int16_t> test_input_block =
|
|
||||||
Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16);
|
|
||||||
ASSERT_TRUE(test_input_block.Init());
|
|
||||||
Buffer<tran_low_t> test_temp_block =
|
|
||||||
Buffer<tran_low_t>(size_, size_, 0, 16);
|
|
||||||
ASSERT_TRUE(test_temp_block.Init());
|
|
||||||
Buffer<uint8_t> dst = Buffer<uint8_t>(size_, size_, 0, 16);
|
|
||||||
ASSERT_TRUE(dst.Init());
|
|
||||||
Buffer<uint8_t> src = Buffer<uint8_t>(size_, size_, 0, 16);
|
|
||||||
ASSERT_TRUE(src.Init());
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
Buffer<uint16_t> dst16 = Buffer<uint16_t>(size_, size_, 0, 16);
|
|
||||||
ASSERT_TRUE(dst16.Init());
|
|
||||||
Buffer<uint16_t> src16 = Buffer<uint16_t>(size_, size_, 0, 16);
|
|
||||||
ASSERT_TRUE(src16.Init());
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
uint32_t max_error = 0;
|
|
||||||
int64_t total_error = 0;
|
|
||||||
const int count_test_block = 10000;
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
|
||||||
if (bit_depth_ == 8) {
|
|
||||||
src.Set(&rnd, &ACMRandom::Rand8);
|
|
||||||
dst.Set(&rnd, &ACMRandom::Rand8);
|
|
||||||
// Initialize a test block with input range [-255, 255].
|
|
||||||
for (int h = 0; h < size_; ++h) {
|
|
||||||
for (int w = 0; w < size_; ++w) {
|
|
||||||
test_input_block.TopLeftPixel()[h * test_input_block.stride() + w] =
|
|
||||||
src.TopLeftPixel()[h * src.stride() + w] -
|
|
||||||
dst.TopLeftPixel()[h * dst.stride() + w];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
} else {
|
|
||||||
src16.Set(&rnd, 0, max_pixel_value_);
|
|
||||||
dst16.Set(&rnd, 0, max_pixel_value_);
|
|
||||||
for (int h = 0; h < size_; ++h) {
|
|
||||||
for (int w = 0; w < size_; ++w) {
|
|
||||||
test_input_block.TopLeftPixel()[h * test_input_block.stride() + w] =
|
|
||||||
src16.TopLeftPixel()[h * src16.stride() + w] -
|
|
||||||
dst16.TopLeftPixel()[h * dst16.stride() + w];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
}
|
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block, &test_temp_block));
|
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
RunInvTxfm(test_temp_block, dst.TopLeftPixel()));
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
} else {
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16.TopLeftPixel())));
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int h = 0; h < size_; ++h) {
|
|
||||||
for (int w = 0; w < size_; ++w) {
|
|
||||||
int diff;
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
if (bit_depth_ != 8) {
|
|
||||||
diff = dst16.TopLeftPixel()[h * dst16.stride() + w] -
|
|
||||||
src16.TopLeftPixel()[h * src16.stride() + w];
|
|
||||||
} else {
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
diff = dst.TopLeftPixel()[h * dst.stride() + w] -
|
|
||||||
src.TopLeftPixel()[h * src.stride() + w];
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
}
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
const uint32_t error = diff * diff;
|
|
||||||
if (max_error < error) max_error = error;
|
|
||||||
total_error += error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_GE(static_cast<uint32_t>(limit), max_error)
|
|
||||||
<< "Error: 4x4 FHT/IHT has an individual round trip error > " << limit;
|
|
||||||
|
|
||||||
EXPECT_GE(count_test_block * limit, total_error)
|
|
||||||
<< "Error: 4x4 FHT/IHT has average round trip error > " << limit
|
|
||||||
<< " per block";
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunCoeffCheck() {
|
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
||||||
const int count_test_block = 5000;
|
|
||||||
Buffer<int16_t> input_block =
|
|
||||||
Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16);
|
|
||||||
ASSERT_TRUE(input_block.Init());
|
|
||||||
Buffer<tran_low_t> output_ref_block = Buffer<tran_low_t>(size_, size_, 0);
|
|
||||||
ASSERT_TRUE(output_ref_block.Init());
|
|
||||||
Buffer<tran_low_t> output_block = Buffer<tran_low_t>(size_, size_, 0, 16);
|
|
||||||
ASSERT_TRUE(output_block.Init());
|
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
|
||||||
// Initialize a test block with input range [-max_pixel_value_,
|
|
||||||
// max_pixel_value_].
|
|
||||||
input_block.Set(&rnd, -max_pixel_value_, max_pixel_value_);
|
|
||||||
|
|
||||||
fwd_txfm_ref(input_block, &output_ref_block, size_, tx_type_);
|
|
||||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, &output_block));
|
|
||||||
|
|
||||||
// The minimum quant value is 4.
|
|
||||||
EXPECT_TRUE(output_block.CheckValues(output_ref_block));
|
|
||||||
if (::testing::Test::HasFailure()) {
|
|
||||||
printf("Size: %d Transform type: %d\n", size_, tx_type_);
|
|
||||||
output_block.PrintDifference(output_ref_block);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunMemCheck() {
|
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
||||||
const int count_test_block = 5000;
|
|
||||||
Buffer<int16_t> input_extreme_block =
|
|
||||||
Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16);
|
|
||||||
ASSERT_TRUE(input_extreme_block.Init());
|
|
||||||
Buffer<tran_low_t> output_ref_block = Buffer<tran_low_t>(size_, size_, 0);
|
|
||||||
ASSERT_TRUE(output_ref_block.Init());
|
|
||||||
Buffer<tran_low_t> output_block = Buffer<tran_low_t>(size_, size_, 0, 16);
|
|
||||||
ASSERT_TRUE(output_block.Init());
|
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
|
||||||
// Initialize a test block with -max_pixel_value_ or max_pixel_value_.
|
|
||||||
if (i == 0) {
|
|
||||||
input_extreme_block.Set(max_pixel_value_);
|
|
||||||
} else if (i == 1) {
|
|
||||||
input_extreme_block.Set(-max_pixel_value_);
|
|
||||||
} else {
|
|
||||||
for (int h = 0; h < size_; ++h) {
|
|
||||||
for (int w = 0; w < size_; ++w) {
|
|
||||||
input_extreme_block
|
|
||||||
.TopLeftPixel()[h * input_extreme_block.stride() + w] =
|
|
||||||
rnd.Rand8() % 2 ? max_pixel_value_ : -max_pixel_value_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fwd_txfm_ref(input_extreme_block, &output_ref_block, size_, tx_type_);
|
|
||||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block, &output_block));
|
|
||||||
|
|
||||||
// The minimum quant value is 4.
|
|
||||||
EXPECT_TRUE(output_block.CheckValues(output_ref_block));
|
|
||||||
for (int h = 0; h < size_; ++h) {
|
|
||||||
for (int w = 0; w < size_; ++w) {
|
|
||||||
EXPECT_GE(
|
|
||||||
4 * DCT_MAX_VALUE << (bit_depth_ - 8),
|
|
||||||
abs(output_block.TopLeftPixel()[h * output_block.stride() + w]))
|
|
||||||
<< "Error: 4x4 FDCT has coefficient larger than "
|
|
||||||
"4*DCT_MAX_VALUE"
|
|
||||||
<< " at " << w << "," << h;
|
|
||||||
if (::testing::Test::HasFailure()) {
|
|
||||||
printf("Size: %d Transform type: %d\n", size_, tx_type_);
|
|
||||||
output_block.DumpBuffer();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunInvAccuracyCheck(int limit) {
|
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
||||||
const int count_test_block = 1000;
|
|
||||||
Buffer<int16_t> in = Buffer<int16_t>(size_, size_, 4);
|
|
||||||
ASSERT_TRUE(in.Init());
|
|
||||||
Buffer<tran_low_t> coeff = Buffer<tran_low_t>(size_, size_, 0, 16);
|
|
||||||
ASSERT_TRUE(coeff.Init());
|
|
||||||
Buffer<uint8_t> dst = Buffer<uint8_t>(size_, size_, 0, 16);
|
|
||||||
ASSERT_TRUE(dst.Init());
|
|
||||||
Buffer<uint8_t> src = Buffer<uint8_t>(size_, size_, 0);
|
|
||||||
ASSERT_TRUE(src.Init());
|
|
||||||
Buffer<uint16_t> dst16 = Buffer<uint16_t>(size_, size_, 0, 16);
|
|
||||||
ASSERT_TRUE(dst16.Init());
|
|
||||||
Buffer<uint16_t> src16 = Buffer<uint16_t>(size_, size_, 0);
|
|
||||||
ASSERT_TRUE(src16.Init());
|
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
|
||||||
// Initialize a test block with input range [-max_pixel_value_,
|
|
||||||
// max_pixel_value_].
|
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
|
||||||
src.Set(&rnd, &ACMRandom::Rand8);
|
|
||||||
dst.Set(&rnd, &ACMRandom::Rand8);
|
|
||||||
for (int h = 0; h < size_; ++h) {
|
|
||||||
for (int w = 0; w < size_; ++w) {
|
|
||||||
in.TopLeftPixel()[h * in.stride() + w] =
|
|
||||||
src.TopLeftPixel()[h * src.stride() + w] -
|
|
||||||
dst.TopLeftPixel()[h * dst.stride() + w];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
} else {
|
|
||||||
src16.Set(&rnd, 0, max_pixel_value_);
|
|
||||||
dst16.Set(&rnd, 0, max_pixel_value_);
|
|
||||||
for (int h = 0; h < size_; ++h) {
|
|
||||||
for (int w = 0; w < size_; ++w) {
|
|
||||||
in.TopLeftPixel()[h * in.stride() + w] =
|
|
||||||
src16.TopLeftPixel()[h * src16.stride() + w] -
|
|
||||||
dst16.TopLeftPixel()[h * dst16.stride() + w];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
}
|
|
||||||
|
|
||||||
fwd_txfm_ref(in, &coeff, size_, tx_type_);
|
|
||||||
|
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst.TopLeftPixel()));
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
} else {
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16.TopLeftPixel())));
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int h = 0; h < size_; ++h) {
|
|
||||||
for (int w = 0; w < size_; ++w) {
|
|
||||||
int diff;
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
if (bit_depth_ != 8) {
|
|
||||||
diff = dst16.TopLeftPixel()[h * dst16.stride() + w] -
|
|
||||||
src16.TopLeftPixel()[h * src16.stride() + w];
|
|
||||||
} else {
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
diff = dst.TopLeftPixel()[h * dst.stride() + w] -
|
|
||||||
src.TopLeftPixel()[h * src.stride() + w];
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
}
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
const uint32_t error = diff * diff;
|
|
||||||
EXPECT_GE(static_cast<uint32_t>(limit), error)
|
|
||||||
<< "Error: " << size_ << "x" << size_ << " IDCT has error "
|
|
||||||
<< error << " at " << w << "," << h;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FhtFuncRef fwd_txfm_ref;
|
|
||||||
vpx_bit_depth_t bit_depth_;
|
|
||||||
int tx_type_;
|
|
||||||
int max_pixel_value_;
|
|
||||||
int size_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TransDCT : public TransTestBase,
|
|
||||||
public ::testing::TestWithParam<DctParam> {
|
|
||||||
public:
|
|
||||||
TransDCT() {
|
|
||||||
fwd_txfm_ref = fdct_ref;
|
|
||||||
fwd_txfm_ = GET_PARAM(0);
|
|
||||||
inv_txfm_ = GET_PARAM(1);
|
|
||||||
size_ = GET_PARAM(2);
|
|
||||||
tx_type_ = GET_PARAM(3);
|
|
||||||
bit_depth_ = GET_PARAM(4);
|
|
||||||
max_pixel_value_ = (1 << bit_depth_) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void RunFwdTxfm(const Buffer<int16_t> &in, Buffer<tran_low_t> *out) {
|
|
||||||
fwd_txfm_(in.TopLeftPixel(), out->TopLeftPixel(), in.stride());
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunInvTxfm(const Buffer<tran_low_t> &in, uint8_t *out) {
|
|
||||||
inv_txfm_(in.TopLeftPixel(), out, in.stride());
|
|
||||||
}
|
|
||||||
|
|
||||||
FdctFunc fwd_txfm_;
|
|
||||||
IdctFunc inv_txfm_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(TransDCT, AccuracyCheck) { RunAccuracyCheck(1); }
|
|
||||||
|
|
||||||
TEST_P(TransDCT, CoeffCheck) { RunCoeffCheck(); }
|
|
||||||
|
|
||||||
TEST_P(TransDCT, MemCheck) { RunMemCheck(); }
|
|
||||||
|
|
||||||
TEST_P(TransDCT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
|
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
C, TransDCT,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_highbd_fdct32x32_c, &idct32x32_10, 32, 0, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_fdct32x32_c, &idct32x32_12, 32, 0, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 32, 0,
|
|
||||||
VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_10, 16, 0, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_12, 16, 0, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 16, 0,
|
|
||||||
VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_10, 8, 0, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_12, 8, 0, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c, 8, 0, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_10, 4, 0, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_12, 4, 0, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c, 4, 0, VPX_BITS_8)));
|
|
||||||
#else
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
C, TransDCT,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 32, 0,
|
|
||||||
VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 16, 0,
|
|
||||||
VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c, 8, 0, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c, 4, 0, VPX_BITS_8)));
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
|
|
||||||
#if HAVE_SSE2
|
|
||||||
#if !CONFIG_EMULATE_HARDWARE
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
/* TODO:(johannkoenig) Determine why these fail AccuracyCheck
|
|
||||||
make_tuple(&vpx_highbd_fdct32x32_sse2, &idct32x32_12, 32, 0, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_12, 16, 0, VPX_BITS_12),
|
|
||||||
*/
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE2, TransDCT,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_highbd_fdct32x32_sse2, &idct32x32_10, 32, 0,
|
|
||||||
VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_fdct32x32_sse2, &vpx_idct32x32_1024_add_sse2, 32, 0,
|
|
||||||
VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_10, 16, 0,
|
|
||||||
VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_fdct16x16_sse2, &vpx_idct16x16_256_add_sse2, 16, 0,
|
|
||||||
VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_fdct8x8_sse2, &idct8x8_10, 8, 0, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_fdct8x8_sse2, &idct8x8_12, 8, 0, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_sse2, 8, 0,
|
|
||||||
VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_fdct4x4_sse2, &idct4x4_10, 4, 0, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_fdct4x4_sse2, &idct4x4_12, 4, 0, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_fdct4x4_sse2, &vpx_idct4x4_16_add_sse2, 4, 0,
|
|
||||||
VPX_BITS_8)));
|
|
||||||
#else
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE2, TransDCT,
|
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_sse2,
|
|
||||||
&vpx_idct32x32_1024_add_sse2, 32, 0,
|
|
||||||
VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct16x16_sse2,
|
|
||||||
&vpx_idct16x16_256_add_sse2, 16, 0,
|
|
||||||
VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_sse2, 8,
|
|
||||||
0, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct4x4_sse2, &vpx_idct4x4_16_add_sse2, 4,
|
|
||||||
0, VPX_BITS_8)));
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
#endif // !CONFIG_EMULATE_HARDWARE
|
|
||||||
#endif // HAVE_SSE2
|
|
||||||
|
|
||||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
#if HAVE_SSSE3 && !CONFIG_EMULATE_HARDWARE
|
|
||||||
#if !ARCH_X86_64
|
|
||||||
// TODO(johannkoenig): high bit depth fdct8x8.
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSSE3, TransDCT,
|
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_sse2,
|
|
||||||
32, 0, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_sse2, 8, 0,
|
|
||||||
VPX_BITS_8)));
|
|
||||||
#else
|
|
||||||
// vpx_fdct8x8_ssse3 is only available in 64 bit builds.
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSSE3, TransDCT,
|
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_sse2,
|
|
||||||
32, 0, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct8x8_ssse3, &vpx_idct8x8_64_add_sse2,
|
|
||||||
8, 0, VPX_BITS_8)));
|
|
||||||
#endif // !ARCH_X86_64
|
|
||||||
#endif // HAVE_SSSE3 && !CONFIG_EMULATE_HARDWARE
|
|
||||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
|
|
||||||
#if !CONFIG_VP9_HIGHBITDEPTH && HAVE_AVX2 && !CONFIG_EMULATE_HARDWARE
|
|
||||||
// TODO(johannkoenig): high bit depth fdct32x32.
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
AVX2, TransDCT, ::testing::Values(make_tuple(&vpx_fdct32x32_avx2,
|
|
||||||
&vpx_idct32x32_1024_add_sse2,
|
|
||||||
32, 0, VPX_BITS_8)));
|
|
||||||
|
|
||||||
#endif // !CONFIG_VP9_HIGHBITDEPTH && HAVE_AVX2 && !CONFIG_EMULATE_HARDWARE
|
|
||||||
|
|
||||||
#if HAVE_NEON
|
|
||||||
#if !CONFIG_EMULATE_HARDWARE
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
NEON, TransDCT,
|
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_neon,
|
|
||||||
&vpx_idct32x32_1024_add_neon, 32, 0,
|
|
||||||
VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct16x16_neon,
|
|
||||||
&vpx_idct16x16_256_add_neon, 16, 0,
|
|
||||||
VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct8x8_neon, &vpx_idct8x8_64_add_neon, 8,
|
|
||||||
0, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct4x4_neon, &vpx_idct4x4_16_add_neon, 4,
|
|
||||||
0, VPX_BITS_8)));
|
|
||||||
#endif // !CONFIG_EMULATE_HARDWARE
|
|
||||||
#endif // HAVE_NEON
|
|
||||||
|
|
||||||
#if HAVE_MSA
|
|
||||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
#if !CONFIG_EMULATE_HARDWARE
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MSA, TransDCT,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_fdct32x32_msa, &vpx_idct32x32_1024_add_msa, 32, 0,
|
|
||||||
VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct16x16_msa, &vpx_idct16x16_256_add_msa, 16, 0,
|
|
||||||
VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct8x8_msa, &vpx_idct8x8_64_add_msa, 8, 0, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct4x4_msa, &vpx_idct4x4_16_add_msa, 4, 0,
|
|
||||||
VPX_BITS_8)));
|
|
||||||
#endif // !CONFIG_EMULATE_HARDWARE
|
|
||||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
#endif // HAVE_MSA
|
|
||||||
|
|
||||||
#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
INSTANTIATE_TEST_CASE_P(VSX, TransDCT,
|
|
||||||
::testing::Values(make_tuple(&vpx_fdct4x4_c,
|
|
||||||
&vpx_idct4x4_16_add_vsx, 4,
|
|
||||||
0, VPX_BITS_8)));
|
|
||||||
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
|
|
||||||
class TransHT : public TransTestBase, public ::testing::TestWithParam<HtParam> {
|
|
||||||
public:
|
|
||||||
TransHT() {
|
|
||||||
fwd_txfm_ref = fht_ref;
|
|
||||||
fwd_txfm_ = GET_PARAM(0);
|
|
||||||
inv_txfm_ = GET_PARAM(1);
|
|
||||||
size_ = GET_PARAM(2);
|
|
||||||
tx_type_ = GET_PARAM(3);
|
|
||||||
bit_depth_ = GET_PARAM(4);
|
|
||||||
max_pixel_value_ = (1 << bit_depth_) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void RunFwdTxfm(const Buffer<int16_t> &in, Buffer<tran_low_t> *out) {
|
|
||||||
fwd_txfm_(in.TopLeftPixel(), out->TopLeftPixel(), in.stride(), tx_type_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunInvTxfm(const Buffer<tran_low_t> &in, uint8_t *out) {
|
|
||||||
inv_txfm_(in.TopLeftPixel(), out, in.stride(), tx_type_);
|
|
||||||
}
|
|
||||||
|
|
||||||
FhtFunc fwd_txfm_;
|
|
||||||
IhtFunc inv_txfm_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(TransHT, AccuracyCheck) { RunAccuracyCheck(1); }
|
|
||||||
|
|
||||||
TEST_P(TransHT, CoeffCheck) { RunCoeffCheck(); }
|
|
||||||
|
|
||||||
TEST_P(TransHT, MemCheck) { RunMemCheck(); }
|
|
||||||
|
|
||||||
TEST_P(TransHT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
|
|
||||||
|
|
||||||
/* TODO:(johannkoenig) Determine why these fail AccuracyCheck
|
|
||||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 16, 0, VPX_BITS_12),
|
|
||||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 16, 1, VPX_BITS_12),
|
|
||||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 16, 2, VPX_BITS_12),
|
|
||||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 16, 3, VPX_BITS_12),
|
|
||||||
*/
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
C, TransHT,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 16, 0, VPX_BITS_10),
|
|
||||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 16, 1, VPX_BITS_10),
|
|
||||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 16, 2, VPX_BITS_10),
|
|
||||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 16, 3, VPX_BITS_10),
|
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 0, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 1, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 2, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 3, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 8, 0, VPX_BITS_10),
|
|
||||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 8, 1, VPX_BITS_10),
|
|
||||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 8, 2, VPX_BITS_10),
|
|
||||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 8, 3, VPX_BITS_10),
|
|
||||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 8, 0, VPX_BITS_12),
|
|
||||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 8, 1, VPX_BITS_12),
|
|
||||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 8, 2, VPX_BITS_12),
|
|
||||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 8, 3, VPX_BITS_12),
|
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 0, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 1, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 2, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 3, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 4, 0, VPX_BITS_10),
|
|
||||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 4, 1, VPX_BITS_10),
|
|
||||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 4, 2, VPX_BITS_10),
|
|
||||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 4, 3, VPX_BITS_10),
|
|
||||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 4, 0, VPX_BITS_12),
|
|
||||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 4, 1, VPX_BITS_12),
|
|
||||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 4, 2, VPX_BITS_12),
|
|
||||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 4, 3, VPX_BITS_12),
|
|
||||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 0, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 1, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 2, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 3, VPX_BITS_8)));
|
|
||||||
#else
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
C, TransHT,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 0, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 1, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 2, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 3, VPX_BITS_8),
|
|
||||||
|
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 0, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 1, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 2, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 3, VPX_BITS_8),
|
|
||||||
|
|
||||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 0, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 1, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 2, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 3, VPX_BITS_8)));
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
|
|
||||||
#if HAVE_SSE2
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE2, TransHT,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 16, 0,
|
|
||||||
VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 16, 1,
|
|
||||||
VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 16, 2,
|
|
||||||
VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 16, 3,
|
|
||||||
VPX_BITS_8),
|
|
||||||
|
|
||||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 8, 0, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 8, 1, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 8, 2, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 8, 3, VPX_BITS_8),
|
|
||||||
|
|
||||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 4, 0, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 4, 1, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 4, 2, VPX_BITS_8),
|
|
||||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 4, 3,
|
|
||||||
VPX_BITS_8)));
|
|
||||||
#endif // HAVE_SSE2
|
|
||||||
|
|
||||||
class TransWHT : public TransTestBase,
|
|
||||||
public ::testing::TestWithParam<DctParam> {
|
|
||||||
public:
|
|
||||||
TransWHT() {
|
|
||||||
fwd_txfm_ref = fwht_ref;
|
|
||||||
fwd_txfm_ = GET_PARAM(0);
|
|
||||||
inv_txfm_ = GET_PARAM(1);
|
|
||||||
size_ = GET_PARAM(2);
|
|
||||||
tx_type_ = GET_PARAM(3);
|
|
||||||
bit_depth_ = GET_PARAM(4);
|
|
||||||
max_pixel_value_ = (1 << bit_depth_) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void RunFwdTxfm(const Buffer<int16_t> &in, Buffer<tran_low_t> *out) {
|
|
||||||
fwd_txfm_(in.TopLeftPixel(), out->TopLeftPixel(), in.stride());
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunInvTxfm(const Buffer<tran_low_t> &in, uint8_t *out) {
|
|
||||||
inv_txfm_(in.TopLeftPixel(), out, in.stride());
|
|
||||||
}
|
|
||||||
|
|
||||||
FdctFunc fwd_txfm_;
|
|
||||||
IdctFunc inv_txfm_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(TransWHT, AccuracyCheck) { RunAccuracyCheck(0); }
|
|
||||||
|
|
||||||
TEST_P(TransWHT, CoeffCheck) { RunCoeffCheck(); }
|
|
||||||
|
|
||||||
TEST_P(TransWHT, MemCheck) { RunMemCheck(); }
|
|
||||||
|
|
||||||
TEST_P(TransWHT, InvAccuracyCheck) { RunInvAccuracyCheck(0); }
|
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
C, TransWHT,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vp9_highbd_fwht4x4_c, &iwht4x4_10, 4, 0, VPX_BITS_10),
|
|
||||||
make_tuple(&vp9_highbd_fwht4x4_c, &iwht4x4_12, 4, 0, VPX_BITS_12),
|
|
||||||
make_tuple(&vp9_fwht4x4_c, &vpx_iwht4x4_16_add_c, 4, 0, VPX_BITS_8)));
|
|
||||||
#else
|
|
||||||
INSTANTIATE_TEST_CASE_P(C, TransWHT,
|
|
||||||
::testing::Values(make_tuple(&vp9_fwht4x4_c,
|
|
||||||
&vpx_iwht4x4_16_add_c, 4,
|
|
||||||
0, VPX_BITS_8)));
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
|
|
||||||
#if HAVE_SSE2
|
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, TransWHT,
|
|
||||||
::testing::Values(make_tuple(&vp9_fwht4x4_sse2,
|
|
||||||
&vpx_iwht4x4_16_add_sse2,
|
|
||||||
4, 0, VPX_BITS_8)));
|
|
||||||
#endif // HAVE_SSE2
|
|
||||||
} // namespace
|
|
||||||
@@ -21,11 +21,8 @@ namespace {
|
|||||||
|
|
||||||
TEST(DecodeAPI, InvalidParams) {
|
TEST(DecodeAPI, InvalidParams) {
|
||||||
static const vpx_codec_iface_t *kCodecs[] = {
|
static const vpx_codec_iface_t *kCodecs[] = {
|
||||||
#if CONFIG_VP8_DECODER
|
#if CONFIG_VP10_DECODER
|
||||||
&vpx_codec_vp8_dx_algo,
|
&vpx_codec_vp10_dx_algo,
|
||||||
#endif
|
|
||||||
#if CONFIG_VP9_DECODER
|
|
||||||
&vpx_codec_vp9_dx_algo,
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
uint8_t buf[1] = {0};
|
uint8_t buf[1] = {0};
|
||||||
@@ -51,142 +48,11 @@ TEST(DecodeAPI, InvalidParams) {
|
|||||||
vpx_codec_decode(&dec, buf, NELEMENTS(buf), NULL, 0));
|
vpx_codec_decode(&dec, buf, NELEMENTS(buf), NULL, 0));
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||||
vpx_codec_decode(&dec, NULL, NELEMENTS(buf), NULL, 0));
|
vpx_codec_decode(&dec, NULL, NELEMENTS(buf), NULL, 0));
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_decode(&dec, buf, 0, NULL, 0));
|
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||||
|
vpx_codec_decode(&dec, buf, 0, NULL, 0));
|
||||||
|
|
||||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
|
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_VP8_DECODER
|
|
||||||
TEST(DecodeAPI, OptionalParams) {
|
|
||||||
vpx_codec_ctx_t dec;
|
|
||||||
|
|
||||||
#if CONFIG_ERROR_CONCEALMENT
|
|
||||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, &vpx_codec_vp8_dx_algo, NULL,
|
|
||||||
VPX_CODEC_USE_ERROR_CONCEALMENT));
|
|
||||||
#else
|
|
||||||
EXPECT_EQ(VPX_CODEC_INCAPABLE,
|
|
||||||
vpx_codec_dec_init(&dec, &vpx_codec_vp8_dx_algo, NULL,
|
|
||||||
VPX_CODEC_USE_ERROR_CONCEALMENT));
|
|
||||||
#endif // CONFIG_ERROR_CONCEALMENT
|
|
||||||
}
|
|
||||||
#endif // CONFIG_VP8_DECODER
|
|
||||||
|
|
||||||
#if CONFIG_VP9_DECODER
|
|
||||||
// Test VP9 codec controls after a decode error to ensure the code doesn't
|
|
||||||
// misbehave.
|
|
||||||
void TestVp9Controls(vpx_codec_ctx_t *dec) {
|
|
||||||
static const int kControls[] = { VP8D_GET_LAST_REF_UPDATES,
|
|
||||||
VP8D_GET_FRAME_CORRUPTED,
|
|
||||||
VP9D_GET_DISPLAY_SIZE, VP9D_GET_FRAME_SIZE };
|
|
||||||
int val[2];
|
|
||||||
|
|
||||||
for (int i = 0; i < NELEMENTS(kControls); ++i) {
|
|
||||||
const vpx_codec_err_t res = vpx_codec_control_(dec, kControls[i], val);
|
|
||||||
switch (kControls[i]) {
|
|
||||||
case VP8D_GET_FRAME_CORRUPTED:
|
|
||||||
EXPECT_EQ(VPX_CODEC_ERROR, res) << kControls[i];
|
|
||||||
break;
|
|
||||||
default: EXPECT_EQ(VPX_CODEC_OK, res) << kControls[i]; break;
|
|
||||||
}
|
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
|
||||||
vpx_codec_control_(dec, kControls[i], NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
vp9_ref_frame_t ref;
|
|
||||||
ref.idx = 0;
|
|
||||||
EXPECT_EQ(VPX_CODEC_ERROR, vpx_codec_control(dec, VP9_GET_REFERENCE, &ref));
|
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
|
||||||
vpx_codec_control(dec, VP9_GET_REFERENCE, NULL));
|
|
||||||
|
|
||||||
vpx_ref_frame_t ref_copy;
|
|
||||||
const int width = 352;
|
|
||||||
const int height = 288;
|
|
||||||
ASSERT_TRUE(
|
|
||||||
vpx_img_alloc(&ref_copy.img, VPX_IMG_FMT_I420, width, height, 1) != NULL);
|
|
||||||
ref_copy.frame_type = VP8_LAST_FRAME;
|
|
||||||
EXPECT_EQ(VPX_CODEC_ERROR,
|
|
||||||
vpx_codec_control(dec, VP8_COPY_REFERENCE, &ref_copy));
|
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
|
||||||
vpx_codec_control(dec, VP8_COPY_REFERENCE, NULL));
|
|
||||||
vpx_img_free(&ref_copy.img);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(DecodeAPI, Vp9InvalidDecode) {
|
|
||||||
const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo;
|
|
||||||
const char filename[] =
|
|
||||||
"invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf";
|
|
||||||
libvpx_test::IVFVideoSource video(filename);
|
|
||||||
video.Init();
|
|
||||||
video.Begin();
|
|
||||||
ASSERT_TRUE(!HasFailure());
|
|
||||||
|
|
||||||
vpx_codec_ctx_t dec;
|
|
||||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
|
|
||||||
const uint32_t frame_size = static_cast<uint32_t>(video.frame_size());
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
EXPECT_EQ(VPX_CODEC_MEM_ERROR,
|
|
||||||
vpx_codec_decode(&dec, video.cxdata(), frame_size, NULL, 0));
|
|
||||||
#else
|
|
||||||
EXPECT_EQ(VPX_CODEC_UNSUP_BITSTREAM,
|
|
||||||
vpx_codec_decode(&dec, video.cxdata(), frame_size, NULL, 0));
|
|
||||||
#endif
|
|
||||||
vpx_codec_iter_t iter = NULL;
|
|
||||||
EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));
|
|
||||||
|
|
||||||
TestVp9Controls(&dec);
|
|
||||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(DecodeAPI, Vp9PeekSI) {
|
|
||||||
const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo;
|
|
||||||
// The first 9 bytes are valid and the rest of the bytes are made up. Until
|
|
||||||
// size 10, this should return VPX_CODEC_UNSUP_BITSTREAM and after that it
|
|
||||||
// should return VPX_CODEC_CORRUPT_FRAME.
|
|
||||||
const uint8_t data[32] = {
|
|
||||||
0x85, 0xa4, 0xc1, 0xa1, 0x38, 0x81, 0xa3, 0x49, 0x83, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
};
|
|
||||||
|
|
||||||
for (uint32_t data_sz = 1; data_sz <= 32; ++data_sz) {
|
|
||||||
// Verify behavior of vpx_codec_decode. vpx_codec_decode doesn't even get
|
|
||||||
// to decoder_peek_si_internal on frames of size < 8.
|
|
||||||
if (data_sz >= 8) {
|
|
||||||
vpx_codec_ctx_t dec;
|
|
||||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
|
|
||||||
EXPECT_EQ(
|
|
||||||
(data_sz < 10) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_CORRUPT_FRAME,
|
|
||||||
vpx_codec_decode(&dec, data, data_sz, NULL, 0));
|
|
||||||
vpx_codec_iter_t iter = NULL;
|
|
||||||
EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));
|
|
||||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify behavior of vpx_codec_peek_stream_info.
|
|
||||||
vpx_codec_stream_info_t si;
|
|
||||||
si.sz = sizeof(si);
|
|
||||||
EXPECT_EQ((data_sz < 10) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_OK,
|
|
||||||
vpx_codec_peek_stream_info(codec, data, data_sz, &si));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // CONFIG_VP9_DECODER
|
|
||||||
|
|
||||||
TEST(DecodeAPI, HighBitDepthCapability) {
|
|
||||||
// VP8 should not claim VP9 HBD as a capability.
|
|
||||||
#if CONFIG_VP8_DECODER
|
|
||||||
const vpx_codec_caps_t vp8_caps = vpx_codec_get_caps(&vpx_codec_vp8_dx_algo);
|
|
||||||
EXPECT_EQ(vp8_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_VP9_DECODER
|
|
||||||
const vpx_codec_caps_t vp9_caps = vpx_codec_get_caps(&vpx_codec_vp9_dx_algo);
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, VPX_CODEC_CAP_HIGHBITDEPTH);
|
|
||||||
#else
|
|
||||||
EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ namespace {
|
|||||||
#define VIDEO_NAME 0
|
#define VIDEO_NAME 0
|
||||||
#define THREADS 1
|
#define THREADS 1
|
||||||
|
|
||||||
|
const int kMaxPsnr = 100;
|
||||||
const double kUsecsInSec = 1000000.0;
|
const double kUsecsInSec = 1000000.0;
|
||||||
const char kNewEncodeOutputFile[] = "new_encode.ivf";
|
const char kNewEncodeOutputFile[] = "new_encode.ivf";
|
||||||
|
|
||||||
@@ -69,7 +70,8 @@ const DecodePerfParam kVP9DecodePerfVectors[] = {
|
|||||||
power/temp/min max frame decode times/etc
|
power/temp/min max frame decode times/etc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class DecodePerfTest : public ::testing::TestWithParam<DecodePerfParam> {};
|
class DecodePerfTest : public ::testing::TestWithParam<DecodePerfParam> {
|
||||||
|
};
|
||||||
|
|
||||||
TEST_P(DecodePerfTest, PerfTest) {
|
TEST_P(DecodePerfTest, PerfTest) {
|
||||||
const char *const video_name = GET_PARAM(VIDEO_NAME);
|
const char *const video_name = GET_PARAM(VIDEO_NAME);
|
||||||
@@ -90,7 +92,8 @@ TEST_P(DecodePerfTest, PerfTest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vpx_usec_timer_mark(&t);
|
vpx_usec_timer_mark(&t);
|
||||||
const double elapsed_secs = double(vpx_usec_timer_elapsed(&t)) / kUsecsInSec;
|
const double elapsed_secs = double(vpx_usec_timer_elapsed(&t))
|
||||||
|
/ kUsecsInSec;
|
||||||
const unsigned frames = video.frame_number();
|
const unsigned frames = video.frame_number();
|
||||||
const double fps = double(frames) / elapsed_secs;
|
const double fps = double(frames) / elapsed_secs;
|
||||||
|
|
||||||
@@ -108,13 +111,17 @@ TEST_P(DecodePerfTest, PerfTest) {
|
|||||||
INSTANTIATE_TEST_CASE_P(VP9, DecodePerfTest,
|
INSTANTIATE_TEST_CASE_P(VP9, DecodePerfTest,
|
||||||
::testing::ValuesIn(kVP9DecodePerfVectors));
|
::testing::ValuesIn(kVP9DecodePerfVectors));
|
||||||
|
|
||||||
class VP9NewEncodeDecodePerfTest
|
class VP9NewEncodeDecodePerfTest :
|
||||||
: public ::libvpx_test::EncoderTest,
|
public ::libvpx_test::EncoderTest,
|
||||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||||
protected:
|
protected:
|
||||||
VP9NewEncodeDecodePerfTest()
|
VP9NewEncodeDecodePerfTest()
|
||||||
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)), speed_(0),
|
: EncoderTest(GET_PARAM(0)),
|
||||||
outfile_(0), out_frames_(0) {}
|
encoding_mode_(GET_PARAM(1)),
|
||||||
|
speed_(0),
|
||||||
|
outfile_(0),
|
||||||
|
out_frames_(0) {
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~VP9NewEncodeDecodePerfTest() {}
|
virtual ~VP9NewEncodeDecodePerfTest() {}
|
||||||
|
|
||||||
@@ -153,9 +160,8 @@ class VP9NewEncodeDecodePerfTest
|
|||||||
|
|
||||||
virtual void EndPassHook() {
|
virtual void EndPassHook() {
|
||||||
if (outfile_ != NULL) {
|
if (outfile_ != NULL) {
|
||||||
if (!fseek(outfile_, 0, SEEK_SET)) {
|
if (!fseek(outfile_, 0, SEEK_SET))
|
||||||
ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_);
|
ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_);
|
||||||
}
|
|
||||||
fclose(outfile_);
|
fclose(outfile_);
|
||||||
outfile_ = NULL;
|
outfile_ = NULL;
|
||||||
}
|
}
|
||||||
@@ -165,9 +171,8 @@ class VP9NewEncodeDecodePerfTest
|
|||||||
++out_frames_;
|
++out_frames_;
|
||||||
|
|
||||||
// Write initial file header if first frame.
|
// Write initial file header if first frame.
|
||||||
if (pkt->data.frame.pts == 0) {
|
if (pkt->data.frame.pts == 0)
|
||||||
ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_);
|
ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_);
|
||||||
}
|
|
||||||
|
|
||||||
// Write frame header and data.
|
// Write frame header and data.
|
||||||
ivf_write_frame_header(outfile_, out_frames_, pkt->data.frame.sz);
|
ivf_write_frame_header(outfile_, out_frames_, pkt->data.frame.sz);
|
||||||
@@ -175,9 +180,11 @@ class VP9NewEncodeDecodePerfTest
|
|||||||
pkt->data.frame.sz);
|
pkt->data.frame.sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool DoDecode() const { return false; }
|
virtual bool DoDecode() { return false; }
|
||||||
|
|
||||||
void set_speed(unsigned int speed) { speed_ = speed; }
|
void set_speed(unsigned int speed) {
|
||||||
|
speed_ = speed;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
libvpx_test::TestMode encoding_mode_;
|
libvpx_test::TestMode encoding_mode_;
|
||||||
@@ -189,7 +196,10 @@ class VP9NewEncodeDecodePerfTest
|
|||||||
struct EncodePerfTestVideo {
|
struct EncodePerfTestVideo {
|
||||||
EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_,
|
EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_,
|
||||||
uint32_t bitrate_, int frames_)
|
uint32_t bitrate_, int frames_)
|
||||||
: name(name_), width(width_), height(height_), bitrate(bitrate_),
|
: name(name_),
|
||||||
|
width(width_),
|
||||||
|
height(height_),
|
||||||
|
bitrate(bitrate_),
|
||||||
frames(frames_) {}
|
frames(frames_) {}
|
||||||
const char *name;
|
const char *name;
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
@@ -215,8 +225,10 @@ TEST_P(VP9NewEncodeDecodePerfTest, PerfTest) {
|
|||||||
|
|
||||||
const char *video_name = kVP9EncodePerfTestVectors[i].name;
|
const char *video_name = kVP9EncodePerfTestVectors[i].name;
|
||||||
libvpx_test::I420VideoSource video(
|
libvpx_test::I420VideoSource video(
|
||||||
video_name, kVP9EncodePerfTestVectors[i].width,
|
video_name,
|
||||||
kVP9EncodePerfTestVectors[i].height, timebase.den, timebase.num, 0,
|
kVP9EncodePerfTestVectors[i].width,
|
||||||
|
kVP9EncodePerfTestVectors[i].height,
|
||||||
|
timebase.den, timebase.num, 0,
|
||||||
kVP9EncodePerfTestVectors[i].frames);
|
kVP9EncodePerfTestVectors[i].frames);
|
||||||
set_speed(2);
|
set_speed(2);
|
||||||
|
|
||||||
@@ -256,6 +268,6 @@ TEST_P(VP9NewEncodeDecodePerfTest, PerfTest) {
|
|||||||
printf("}\n");
|
printf("}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(VP9NewEncodeDecodePerfTest,
|
VP10_INSTANTIATE_TEST_CASE(
|
||||||
::testing::Values(::libvpx_test::kTwoPassGood));
|
VP9NewEncodeDecodePerfTest, ::testing::Values(::libvpx_test::kTwoPassGood));
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -1,124 +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 <string>
|
|
||||||
|
|
||||||
#include "test/codec_factory.h"
|
|
||||||
#include "test/decode_test_driver.h"
|
|
||||||
#include "test/ivf_video_source.h"
|
|
||||||
#include "test/test_vectors.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
const unsigned int kNumFrames = 19;
|
|
||||||
|
|
||||||
class DecodeSvcTest : public ::libvpx_test::DecoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWithParam<const char *> {
|
|
||||||
protected:
|
|
||||||
DecodeSvcTest() : DecoderTest(GET_PARAM(::libvpx_test::kCodecFactoryParam)) {}
|
|
||||||
virtual ~DecodeSvcTest() {}
|
|
||||||
|
|
||||||
virtual void PreDecodeFrameHook(
|
|
||||||
const libvpx_test::CompressedVideoSource &video,
|
|
||||||
libvpx_test::Decoder *decoder) {
|
|
||||||
if (video.frame_number() == 0)
|
|
||||||
decoder->Control(VP9_DECODE_SVC_SPATIAL_LAYER, spatial_layer_);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
|
||||||
const unsigned int frame_number) {
|
|
||||||
ASSERT_EQ(img.d_w, width_);
|
|
||||||
ASSERT_EQ(img.d_h, height_);
|
|
||||||
total_frames_ = frame_number;
|
|
||||||
}
|
|
||||||
|
|
||||||
int spatial_layer_;
|
|
||||||
unsigned int width_;
|
|
||||||
unsigned int height_;
|
|
||||||
unsigned int total_frames_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// SVC test vector is 1280x720, with 3 spatial layers, and 20 frames.
|
|
||||||
|
|
||||||
// Decode the SVC test vector, which has 3 spatial layers, and decode up to
|
|
||||||
// spatial layer 0. Verify the resolution of each decoded frame and the total
|
|
||||||
// number of frames decoded. This results in 1/4x1/4 resolution (320x180).
|
|
||||||
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer0) {
|
|
||||||
const std::string filename = GET_PARAM(1);
|
|
||||||
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
|
||||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
|
||||||
ASSERT_TRUE(video.get() != NULL);
|
|
||||||
video->Init();
|
|
||||||
total_frames_ = 0;
|
|
||||||
spatial_layer_ = 0;
|
|
||||||
width_ = 320;
|
|
||||||
height_ = 180;
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
|
||||||
ASSERT_EQ(total_frames_, kNumFrames);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode the SVC test vector, which has 3 spatial layers, and decode up to
|
|
||||||
// spatial layer 1. Verify the resolution of each decoded frame and the total
|
|
||||||
// number of frames decoded. This results in 1/2x1/2 resolution (640x360).
|
|
||||||
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer1) {
|
|
||||||
const std::string filename = GET_PARAM(1);
|
|
||||||
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
|
||||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
|
||||||
ASSERT_TRUE(video.get() != NULL);
|
|
||||||
video->Init();
|
|
||||||
total_frames_ = 0;
|
|
||||||
spatial_layer_ = 1;
|
|
||||||
width_ = 640;
|
|
||||||
height_ = 360;
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
|
||||||
ASSERT_EQ(total_frames_, kNumFrames);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode the SVC test vector, which has 3 spatial layers, and decode up to
|
|
||||||
// spatial layer 2. Verify the resolution of each decoded frame and the total
|
|
||||||
// number of frames decoded. This results in the full resolution (1280x720).
|
|
||||||
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer2) {
|
|
||||||
const std::string filename = GET_PARAM(1);
|
|
||||||
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
|
||||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
|
||||||
ASSERT_TRUE(video.get() != NULL);
|
|
||||||
video->Init();
|
|
||||||
total_frames_ = 0;
|
|
||||||
spatial_layer_ = 2;
|
|
||||||
width_ = 1280;
|
|
||||||
height_ = 720;
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
|
||||||
ASSERT_EQ(total_frames_, kNumFrames);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode the SVC test vector, which has 3 spatial layers, and decode up to
|
|
||||||
// spatial layer 10. Verify the resolution of each decoded frame and the total
|
|
||||||
// number of frames decoded. This is beyond the number of spatial layers, so
|
|
||||||
// the decoding should result in the full resolution (1280x720).
|
|
||||||
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer10) {
|
|
||||||
const std::string filename = GET_PARAM(1);
|
|
||||||
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
|
||||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
|
||||||
ASSERT_TRUE(video.get() != NULL);
|
|
||||||
video->Init();
|
|
||||||
total_frames_ = 0;
|
|
||||||
spatial_layer_ = 10;
|
|
||||||
width_ = 1280;
|
|
||||||
height_ = 720;
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
|
||||||
ASSERT_EQ(total_frames_, kNumFrames);
|
|
||||||
}
|
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(
|
|
||||||
DecodeSvcTest, ::testing::ValuesIn(libvpx_test::kVP9TestVectorsSvc,
|
|
||||||
libvpx_test::kVP9TestVectorsSvc +
|
|
||||||
libvpx_test::kNumVP9TestVectorsSvc));
|
|
||||||
} // namespace
|
|
||||||
@@ -18,11 +18,13 @@
|
|||||||
namespace libvpx_test {
|
namespace libvpx_test {
|
||||||
|
|
||||||
const char kVP8Name[] = "WebM Project VP8";
|
const char kVP8Name[] = "WebM Project VP8";
|
||||||
|
const char kVP10Name[] = "WebM Project VP10";
|
||||||
|
|
||||||
vpx_codec_err_t Decoder::PeekStream(const uint8_t *cxdata, size_t size,
|
vpx_codec_err_t Decoder::PeekStream(const uint8_t *cxdata, size_t size,
|
||||||
vpx_codec_stream_info_t *stream_info) {
|
vpx_codec_stream_info_t *stream_info) {
|
||||||
return vpx_codec_peek_stream_info(
|
return vpx_codec_peek_stream_info(CodecInterface(),
|
||||||
CodecInterface(), cxdata, static_cast<unsigned int>(size), stream_info);
|
cxdata, static_cast<unsigned int>(size),
|
||||||
|
stream_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size) {
|
vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size) {
|
||||||
@@ -34,8 +36,9 @@ vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size,
|
|||||||
vpx_codec_err_t res_dec;
|
vpx_codec_err_t res_dec;
|
||||||
InitOnce();
|
InitOnce();
|
||||||
API_REGISTER_STATE_CHECK(
|
API_REGISTER_STATE_CHECK(
|
||||||
res_dec = vpx_codec_decode(
|
res_dec = vpx_codec_decode(&decoder_,
|
||||||
&decoder_, cxdata, static_cast<unsigned int>(size), user_priv, 0));
|
cxdata, static_cast<unsigned int>(size),
|
||||||
|
user_priv, 0));
|
||||||
return res_dec;
|
return res_dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,6 +47,11 @@ bool Decoder::IsVP8() const {
|
|||||||
return strncmp(kVP8Name, codec_name, sizeof(kVP8Name) - 1) == 0;
|
return strncmp(kVP8Name, codec_name, sizeof(kVP8Name) - 1) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Decoder::IsVP10() const {
|
||||||
|
const char *codec_name = GetDecoderName();
|
||||||
|
return strncmp(kVP10Name, codec_name, sizeof(kVP10Name) - 1) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
void DecoderTest::HandlePeekResult(Decoder *const decoder,
|
void DecoderTest::HandlePeekResult(Decoder *const decoder,
|
||||||
CompressedVideoSource *video,
|
CompressedVideoSource *video,
|
||||||
const vpx_codec_err_t res_peek) {
|
const vpx_codec_err_t res_peek) {
|
||||||
@@ -53,19 +61,19 @@ void DecoderTest::HandlePeekResult(Decoder *const decoder,
|
|||||||
* pass it is not a keyframe, so we only expect VPX_CODEC_OK on the first
|
* pass it is not a keyframe, so we only expect VPX_CODEC_OK on the first
|
||||||
* frame, which must be a keyframe. */
|
* frame, which must be a keyframe. */
|
||||||
if (video->frame_number() == 0)
|
if (video->frame_number() == 0)
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res_peek)
|
ASSERT_EQ(VPX_CODEC_OK, res_peek) << "Peek return failed: "
|
||||||
<< "Peek return failed: " << vpx_codec_err_to_string(res_peek);
|
<< vpx_codec_err_to_string(res_peek);
|
||||||
} else {
|
} else {
|
||||||
/* The Vp9 implementation of PeekStream returns an error only if the
|
/* The Vp9 implementation of PeekStream returns an error only if the
|
||||||
* data passed to it isn't a valid Vp9 chunk. */
|
* data passed to it isn't a valid Vp9 chunk. */
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res_peek)
|
ASSERT_EQ(VPX_CODEC_OK, res_peek) << "Peek return failed: "
|
||||||
<< "Peek return failed: " << vpx_codec_err_to_string(res_peek);
|
<< vpx_codec_err_to_string(res_peek);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecoderTest::RunLoop(CompressedVideoSource *video,
|
void DecoderTest::RunLoop(CompressedVideoSource *video,
|
||||||
const vpx_codec_dec_cfg_t &dec_cfg) {
|
const vpx_codec_dec_cfg_t &dec_cfg) {
|
||||||
Decoder *const decoder = codec_->CreateDecoder(dec_cfg, flags_);
|
Decoder* const decoder = codec_->CreateDecoder(dec_cfg, flags_, 0);
|
||||||
ASSERT_TRUE(decoder != NULL);
|
ASSERT_TRUE(decoder != NULL);
|
||||||
bool end_of_file = false;
|
bool end_of_file = false;
|
||||||
|
|
||||||
@@ -78,14 +86,16 @@ void DecoderTest::RunLoop(CompressedVideoSource *video,
|
|||||||
stream_info.sz = sizeof(stream_info);
|
stream_info.sz = sizeof(stream_info);
|
||||||
|
|
||||||
if (video->cxdata() != NULL) {
|
if (video->cxdata() != NULL) {
|
||||||
const vpx_codec_err_t res_peek = decoder->PeekStream(
|
const vpx_codec_err_t res_peek = decoder->PeekStream(video->cxdata(),
|
||||||
video->cxdata(), video->frame_size(), &stream_info);
|
video->frame_size(),
|
||||||
|
&stream_info);
|
||||||
HandlePeekResult(decoder, video, res_peek);
|
HandlePeekResult(decoder, video, res_peek);
|
||||||
ASSERT_FALSE(::testing::Test::HasFailure());
|
ASSERT_FALSE(::testing::Test::HasFailure());
|
||||||
|
|
||||||
vpx_codec_err_t res_dec =
|
vpx_codec_err_t res_dec = decoder->DecodeFrame(video->cxdata(),
|
||||||
decoder->DecodeFrame(video->cxdata(), video->frame_size());
|
video->frame_size());
|
||||||
if (!HandleDecodeResult(res_dec, *video, decoder)) break;
|
if (!HandleDecodeResult(res_dec, *video, decoder))
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
// Signal end of the file to the decoder.
|
// Signal end of the file to the decoder.
|
||||||
const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0);
|
const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0);
|
||||||
@@ -97,10 +107,9 @@ void DecoderTest::RunLoop(CompressedVideoSource *video,
|
|||||||
const vpx_image_t *img = NULL;
|
const vpx_image_t *img = NULL;
|
||||||
|
|
||||||
// Get decompressed data
|
// Get decompressed data
|
||||||
while ((img = dec_iter.Next())) {
|
while ((img = dec_iter.Next()))
|
||||||
DecompressedFrameHook(*img, video->frame_number());
|
DecompressedFrameHook(*img, video->frame_number());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
delete decoder;
|
delete decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,6 +122,8 @@ void DecoderTest::set_cfg(const vpx_codec_dec_cfg_t &dec_cfg) {
|
|||||||
memcpy(&cfg_, &dec_cfg, sizeof(cfg_));
|
memcpy(&cfg_, &dec_cfg, sizeof(cfg_));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecoderTest::set_flags(const vpx_codec_flags_t flags) { flags_ = flags; }
|
void DecoderTest::set_flags(const vpx_codec_flags_t flags) {
|
||||||
|
flags_ = flags;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace libvpx_test
|
} // namespace libvpx_test
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ class DxDataIterator {
|
|||||||
explicit DxDataIterator(vpx_codec_ctx_t *decoder)
|
explicit DxDataIterator(vpx_codec_ctx_t *decoder)
|
||||||
: decoder_(decoder), iter_(NULL) {}
|
: decoder_(decoder), iter_(NULL) {}
|
||||||
|
|
||||||
const vpx_image_t *Next() { return vpx_codec_get_frame(decoder_, &iter_); }
|
const vpx_image_t *Next() {
|
||||||
|
return vpx_codec_get_frame(decoder_, &iter_);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vpx_codec_ctx_t *decoder_;
|
vpx_codec_ctx_t *decoder_;
|
||||||
@@ -38,17 +40,20 @@ class DxDataIterator {
|
|||||||
// as more tests are added.
|
// as more tests are added.
|
||||||
class Decoder {
|
class Decoder {
|
||||||
public:
|
public:
|
||||||
explicit Decoder(vpx_codec_dec_cfg_t cfg)
|
Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
|
||||||
: cfg_(cfg), flags_(0), init_done_(false) {
|
: cfg_(cfg), flags_(0), deadline_(deadline), init_done_(false) {
|
||||||
memset(&decoder_, 0, sizeof(decoder_));
|
memset(&decoder_, 0, sizeof(decoder_));
|
||||||
}
|
}
|
||||||
|
|
||||||
Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag)
|
Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
|
||||||
: cfg_(cfg), flags_(flag), init_done_(false) {
|
unsigned long deadline) // NOLINT
|
||||||
|
: cfg_(cfg), flags_(flag), deadline_(deadline), init_done_(false) {
|
||||||
memset(&decoder_, 0, sizeof(decoder_));
|
memset(&decoder_, 0, sizeof(decoder_));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Decoder() { vpx_codec_destroy(&decoder_); }
|
virtual ~Decoder() {
|
||||||
|
vpx_codec_destroy(&decoder_);
|
||||||
|
}
|
||||||
|
|
||||||
vpx_codec_err_t PeekStream(const uint8_t *cxdata, size_t size,
|
vpx_codec_err_t PeekStream(const uint8_t *cxdata, size_t size,
|
||||||
vpx_codec_stream_info_t *stream_info);
|
vpx_codec_stream_info_t *stream_info);
|
||||||
@@ -58,9 +63,17 @@ class Decoder {
|
|||||||
vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size,
|
vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size,
|
||||||
void *user_priv);
|
void *user_priv);
|
||||||
|
|
||||||
DxDataIterator GetDxData() { return DxDataIterator(&decoder_); }
|
DxDataIterator GetDxData() {
|
||||||
|
return DxDataIterator(&decoder_);
|
||||||
|
}
|
||||||
|
|
||||||
void Control(int ctrl_id, int arg) { Control(ctrl_id, arg, VPX_CODEC_OK); }
|
void set_deadline(unsigned long deadline) {
|
||||||
|
deadline_ = deadline;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Control(int ctrl_id, int arg) {
|
||||||
|
Control(ctrl_id, arg, VPX_CODEC_OK);
|
||||||
|
}
|
||||||
|
|
||||||
void Control(int ctrl_id, const void *arg) {
|
void Control(int ctrl_id, const void *arg) {
|
||||||
InitOnce();
|
InitOnce();
|
||||||
@@ -84,8 +97,8 @@ class Decoder {
|
|||||||
vpx_get_frame_buffer_cb_fn_t cb_get,
|
vpx_get_frame_buffer_cb_fn_t cb_get,
|
||||||
vpx_release_frame_buffer_cb_fn_t cb_release, void *user_priv) {
|
vpx_release_frame_buffer_cb_fn_t cb_release, void *user_priv) {
|
||||||
InitOnce();
|
InitOnce();
|
||||||
return vpx_codec_set_frame_buffer_functions(&decoder_, cb_get, cb_release,
|
return vpx_codec_set_frame_buffer_functions(
|
||||||
user_priv);
|
&decoder_, cb_get, cb_release, user_priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* GetDecoderName() const {
|
const char* GetDecoderName() const {
|
||||||
@@ -94,15 +107,20 @@ class Decoder {
|
|||||||
|
|
||||||
bool IsVP8() const;
|
bool IsVP8() const;
|
||||||
|
|
||||||
vpx_codec_ctx_t *GetDecoder() { return &decoder_; }
|
bool IsVP10() const;
|
||||||
|
|
||||||
|
vpx_codec_ctx_t * GetDecoder() {
|
||||||
|
return &decoder_;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual vpx_codec_iface_t* CodecInterface() const = 0;
|
virtual vpx_codec_iface_t* CodecInterface() const = 0;
|
||||||
|
|
||||||
void InitOnce() {
|
void InitOnce() {
|
||||||
if (!init_done_) {
|
if (!init_done_) {
|
||||||
const vpx_codec_err_t res =
|
const vpx_codec_err_t res = vpx_codec_dec_init(&decoder_,
|
||||||
vpx_codec_dec_init(&decoder_, CodecInterface(), &cfg_, flags_);
|
CodecInterface(),
|
||||||
|
&cfg_, flags_);
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError();
|
||||||
init_done_ = true;
|
init_done_ = true;
|
||||||
}
|
}
|
||||||
@@ -111,6 +129,7 @@ class Decoder {
|
|||||||
vpx_codec_ctx_t decoder_;
|
vpx_codec_ctx_t decoder_;
|
||||||
vpx_codec_dec_cfg_t cfg_;
|
vpx_codec_dec_cfg_t cfg_;
|
||||||
vpx_codec_flags_t flags_;
|
vpx_codec_flags_t flags_;
|
||||||
|
unsigned int deadline_;
|
||||||
bool init_done_;
|
bool init_done_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -148,7 +167,9 @@ class DecoderTest {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit DecoderTest(const CodecFactory *codec)
|
explicit DecoderTest(const CodecFactory *codec)
|
||||||
: codec_(codec), cfg_(), flags_(0) {}
|
: codec_(codec),
|
||||||
|
cfg_(),
|
||||||
|
flags_(0) {}
|
||||||
|
|
||||||
virtual ~DecoderTest() {}
|
virtual ~DecoderTest() {}
|
||||||
|
|
||||||
|
|||||||
100
test/denoiser_sse2_test.cc
Normal file
100
test/denoiser_sse2_test.cc
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
#include "test/acm_random.h"
|
||||||
|
#include "test/clear_system_state.h"
|
||||||
|
#include "test/register_state_check.h"
|
||||||
|
#include "test/util.h"
|
||||||
|
|
||||||
|
#include "vpx_scale/yv12config.h"
|
||||||
|
#include "vpx/vpx_integer.h"
|
||||||
|
#include "vp10/common/reconinter.h"
|
||||||
|
#include "vp10/encoder/context_tree.h"
|
||||||
|
#include "vp10/encoder/denoiser.h"
|
||||||
|
|
||||||
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const int kNumPixels = 64 * 64;
|
||||||
|
class VP9DenoiserTest : public ::testing::TestWithParam<BLOCK_SIZE> {
|
||||||
|
public:
|
||||||
|
virtual ~VP9DenoiserTest() {}
|
||||||
|
|
||||||
|
virtual void SetUp() {
|
||||||
|
bs_ = GetParam();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BLOCK_SIZE bs_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(VP9DenoiserTest, BitexactCheck) {
|
||||||
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
|
const int count_test_block = 4000;
|
||||||
|
|
||||||
|
// Allocate the space for input and output,
|
||||||
|
// where sig_block is the block to be denoised,
|
||||||
|
// mc_avg_block is the denoised reference block,
|
||||||
|
// avg_block_c is the denoised result from C code,
|
||||||
|
// avg_block_sse2 is the denoised result from SSE2 code.
|
||||||
|
DECLARE_ALIGNED(16, uint8_t, sig_block[kNumPixels]);
|
||||||
|
DECLARE_ALIGNED(16, uint8_t, mc_avg_block[kNumPixels]);
|
||||||
|
DECLARE_ALIGNED(16, uint8_t, avg_block_c[kNumPixels]);
|
||||||
|
DECLARE_ALIGNED(16, uint8_t, avg_block_sse2[kNumPixels]);
|
||||||
|
|
||||||
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
|
// Generate random motion magnitude, 20% of which exceed the threshold.
|
||||||
|
const int motion_magnitude_random =
|
||||||
|
rnd.Rand8() % static_cast<int>(MOTION_MAGNITUDE_THRESHOLD * 1.2);
|
||||||
|
|
||||||
|
// Initialize a test block with random number in range [0, 255].
|
||||||
|
for (int j = 0; j < kNumPixels; ++j) {
|
||||||
|
int temp = 0;
|
||||||
|
sig_block[j] = rnd.Rand8();
|
||||||
|
// The pixels in mc_avg_block are generated by adding a random
|
||||||
|
// number in range [-19, 19] to corresponding pixels in sig_block.
|
||||||
|
temp = sig_block[j] + ((rnd.Rand8() % 2 == 0) ? -1 : 1) *
|
||||||
|
(rnd.Rand8() % 20);
|
||||||
|
// Clip.
|
||||||
|
mc_avg_block[j] = (temp < 0) ? 0 : ((temp > 255) ? 255 : temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASM_REGISTER_STATE_CHECK(vp9_denoiser_filter_c(
|
||||||
|
sig_block, 64, mc_avg_block, 64, avg_block_c,
|
||||||
|
64, 0, bs_, motion_magnitude_random));
|
||||||
|
|
||||||
|
ASM_REGISTER_STATE_CHECK(vp9_denoiser_filter_sse2(
|
||||||
|
sig_block, 64, mc_avg_block, 64, avg_block_sse2,
|
||||||
|
64, 0, bs_, motion_magnitude_random));
|
||||||
|
|
||||||
|
// Test bitexactness.
|
||||||
|
for (int h = 0; h < (4 << b_height_log2_lookup[bs_]); ++h) {
|
||||||
|
for (int w = 0; w < (4 << b_width_log2_lookup[bs_]); ++w) {
|
||||||
|
EXPECT_EQ(avg_block_c[h * 64 + w], avg_block_sse2[h * 64 + w]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for all block size.
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE2, VP9DenoiserTest,
|
||||||
|
::testing::Values(BLOCK_8X8, BLOCK_8X16, BLOCK_16X8, BLOCK_16X16,
|
||||||
|
BLOCK_16X32, BLOCK_32X16, BLOCK_32X32, BLOCK_32X64,
|
||||||
|
BLOCK_64X32, BLOCK_64X64));
|
||||||
|
} // namespace
|
||||||
@@ -20,11 +20,8 @@ namespace {
|
|||||||
|
|
||||||
TEST(EncodeAPI, InvalidParams) {
|
TEST(EncodeAPI, InvalidParams) {
|
||||||
static const vpx_codec_iface_t *kCodecs[] = {
|
static const vpx_codec_iface_t *kCodecs[] = {
|
||||||
#if CONFIG_VP8_ENCODER
|
#if CONFIG_VP10_ENCODER
|
||||||
&vpx_codec_vp8_cx_algo,
|
&vpx_codec_vp10_cx_algo,
|
||||||
#endif
|
|
||||||
#if CONFIG_VP9_ENCODER
|
|
||||||
&vpx_codec_vp9_cx_algo,
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
uint8_t buf[1] = {0};
|
uint8_t buf[1] = {0};
|
||||||
@@ -62,134 +59,4 @@ TEST(EncodeAPI, InvalidParams) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EncodeAPI, HighBitDepthCapability) {
|
|
||||||
// VP8 should not claim VP9 HBD as a capability.
|
|
||||||
#if CONFIG_VP8_ENCODER
|
|
||||||
const vpx_codec_caps_t vp8_caps = vpx_codec_get_caps(&vpx_codec_vp8_cx_algo);
|
|
||||||
EXPECT_EQ(vp8_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_VP9_ENCODER
|
|
||||||
const vpx_codec_caps_t vp9_caps = vpx_codec_get_caps(&vpx_codec_vp9_cx_algo);
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, VPX_CODEC_CAP_HIGHBITDEPTH);
|
|
||||||
#else
|
|
||||||
EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CONFIG_VP8_ENCODER
|
|
||||||
TEST(EncodeAPI, ImageSizeSetting) {
|
|
||||||
const int width = 711;
|
|
||||||
const int height = 360;
|
|
||||||
const int bps = 12;
|
|
||||||
vpx_image_t img;
|
|
||||||
vpx_codec_ctx_t enc;
|
|
||||||
vpx_codec_enc_cfg_t cfg;
|
|
||||||
uint8_t *img_buf = reinterpret_cast<uint8_t *>(
|
|
||||||
calloc(width * height * bps / 8, sizeof(*img_buf)));
|
|
||||||
vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &cfg, 0);
|
|
||||||
|
|
||||||
cfg.g_w = width;
|
|
||||||
cfg.g_h = height;
|
|
||||||
|
|
||||||
vpx_img_wrap(&img, VPX_IMG_FMT_I420, width, height, 1, img_buf);
|
|
||||||
|
|
||||||
vpx_codec_enc_init(&enc, vpx_codec_vp8_cx(), &cfg, 0);
|
|
||||||
|
|
||||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, &img, 0, 1, 0, 0));
|
|
||||||
|
|
||||||
free(img_buf);
|
|
||||||
|
|
||||||
vpx_codec_destroy(&enc);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Set up 2 spatial streams with 2 temporal layers per stream, and generate
|
|
||||||
// invalid configuration by setting the temporal layer rate allocation
|
|
||||||
// (ts_target_bitrate[]) to 0 for both layers. This should fail independent of
|
|
||||||
// CONFIG_MULTI_RES_ENCODING.
|
|
||||||
TEST(EncodeAPI, MultiResEncode) {
|
|
||||||
static const vpx_codec_iface_t *kCodecs[] = {
|
|
||||||
#if CONFIG_VP8_ENCODER
|
|
||||||
&vpx_codec_vp8_cx_algo,
|
|
||||||
#endif
|
|
||||||
#if CONFIG_VP9_ENCODER
|
|
||||||
&vpx_codec_vp9_cx_algo,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
const int width = 1280;
|
|
||||||
const int height = 720;
|
|
||||||
const int width_down = width / 2;
|
|
||||||
const int height_down = height / 2;
|
|
||||||
const int target_bitrate = 1000;
|
|
||||||
const int framerate = 30;
|
|
||||||
|
|
||||||
for (int c = 0; c < NELEMENTS(kCodecs); ++c) {
|
|
||||||
const vpx_codec_iface_t *const iface = kCodecs[c];
|
|
||||||
vpx_codec_ctx_t enc[2];
|
|
||||||
vpx_codec_enc_cfg_t cfg[2];
|
|
||||||
vpx_rational_t dsf[2] = { { 2, 1 }, { 2, 1 } };
|
|
||||||
|
|
||||||
memset(enc, 0, sizeof(enc));
|
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
|
||||||
vpx_codec_enc_config_default(iface, &cfg[i], 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Highest-resolution encoder settings */
|
|
||||||
cfg[0].g_w = width;
|
|
||||||
cfg[0].g_h = height;
|
|
||||||
cfg[0].rc_dropframe_thresh = 0;
|
|
||||||
cfg[0].rc_end_usage = VPX_CBR;
|
|
||||||
cfg[0].rc_resize_allowed = 0;
|
|
||||||
cfg[0].rc_min_quantizer = 2;
|
|
||||||
cfg[0].rc_max_quantizer = 56;
|
|
||||||
cfg[0].rc_undershoot_pct = 100;
|
|
||||||
cfg[0].rc_overshoot_pct = 15;
|
|
||||||
cfg[0].rc_buf_initial_sz = 500;
|
|
||||||
cfg[0].rc_buf_optimal_sz = 600;
|
|
||||||
cfg[0].rc_buf_sz = 1000;
|
|
||||||
cfg[0].g_error_resilient = 1; /* Enable error resilient mode */
|
|
||||||
cfg[0].g_lag_in_frames = 0;
|
|
||||||
|
|
||||||
cfg[0].kf_mode = VPX_KF_AUTO;
|
|
||||||
cfg[0].kf_min_dist = 3000;
|
|
||||||
cfg[0].kf_max_dist = 3000;
|
|
||||||
|
|
||||||
cfg[0].rc_target_bitrate = target_bitrate; /* Set target bitrate */
|
|
||||||
cfg[0].g_timebase.num = 1; /* Set fps */
|
|
||||||
cfg[0].g_timebase.den = framerate;
|
|
||||||
|
|
||||||
memcpy(&cfg[1], &cfg[0], sizeof(cfg[0]));
|
|
||||||
cfg[1].rc_target_bitrate = 500;
|
|
||||||
cfg[1].g_w = width_down;
|
|
||||||
cfg[1].g_h = height_down;
|
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
|
||||||
cfg[i].ts_number_layers = 2;
|
|
||||||
cfg[i].ts_periodicity = 2;
|
|
||||||
cfg[i].ts_rate_decimator[0] = 2;
|
|
||||||
cfg[i].ts_rate_decimator[1] = 1;
|
|
||||||
cfg[i].ts_layer_id[0] = 0;
|
|
||||||
cfg[i].ts_layer_id[1] = 1;
|
|
||||||
// Invalid parameters.
|
|
||||||
cfg[i].ts_target_bitrate[0] = 0;
|
|
||||||
cfg[i].ts_target_bitrate[1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VP9 should report incapable, VP8 invalid for all configurations.
|
|
||||||
const char kVP9Name[] = "WebM Project VP9";
|
|
||||||
const bool is_vp9 = strncmp(kVP9Name, vpx_codec_iface_name(iface),
|
|
||||||
sizeof(kVP9Name) - 1) == 0;
|
|
||||||
EXPECT_EQ(is_vp9 ? VPX_CODEC_INCAPABLE : VPX_CODEC_INVALID_PARAM,
|
|
||||||
vpx_codec_enc_init_multi(&enc[0], iface, &cfg[0], 2, 0, &dsf[0]));
|
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
|
||||||
vpx_codec_destroy(&enc[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -26,7 +26,10 @@ const double kUsecsInSec = 1000000.0;
|
|||||||
struct EncodePerfTestVideo {
|
struct EncodePerfTestVideo {
|
||||||
EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_,
|
EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_,
|
||||||
uint32_t bitrate_, int frames_)
|
uint32_t bitrate_, int frames_)
|
||||||
: name(name_), width(width_), height(height_), bitrate(bitrate_),
|
: name(name_),
|
||||||
|
width(width_),
|
||||||
|
height(height_),
|
||||||
|
bitrate(bitrate_),
|
||||||
frames(frames_) {}
|
frames(frames_) {}
|
||||||
const char *name;
|
const char *name;
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
@@ -42,8 +45,8 @@ const EncodePerfTestVideo kVP9EncodePerfTestVectors[] = {
|
|||||||
EncodePerfTestVideo("macmarcostationary_640_480_30.yuv", 640, 480, 200, 718),
|
EncodePerfTestVideo("macmarcostationary_640_480_30.yuv", 640, 480, 200, 718),
|
||||||
EncodePerfTestVideo("niklas_640_480_30.yuv", 640, 480, 200, 471),
|
EncodePerfTestVideo("niklas_640_480_30.yuv", 640, 480, 200, 471),
|
||||||
EncodePerfTestVideo("tacomanarrows_640_480_30.yuv", 640, 480, 200, 300),
|
EncodePerfTestVideo("tacomanarrows_640_480_30.yuv", 640, 480, 200, 300),
|
||||||
EncodePerfTestVideo("tacomasmallcameramovement_640_480_30.yuv", 640, 480, 200,
|
EncodePerfTestVideo("tacomasmallcameramovement_640_480_30.yuv",
|
||||||
300),
|
640, 480, 200, 300),
|
||||||
EncodePerfTestVideo("thaloundeskmtg_640_480_30.yuv", 640, 480, 200, 300),
|
EncodePerfTestVideo("thaloundeskmtg_640_480_30.yuv", 640, 480, 200, 300),
|
||||||
EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470),
|
EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470),
|
||||||
};
|
};
|
||||||
@@ -58,8 +61,12 @@ class VP9EncodePerfTest
|
|||||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||||
protected:
|
protected:
|
||||||
VP9EncodePerfTest()
|
VP9EncodePerfTest()
|
||||||
: EncoderTest(GET_PARAM(0)), min_psnr_(kMaxPsnr), nframes_(0),
|
: EncoderTest(GET_PARAM(0)),
|
||||||
encoding_mode_(GET_PARAM(1)), speed_(0), threads_(1) {}
|
min_psnr_(kMaxPsnr),
|
||||||
|
nframes_(0),
|
||||||
|
encoding_mode_(GET_PARAM(1)),
|
||||||
|
speed_(0),
|
||||||
|
threads_(1) {}
|
||||||
|
|
||||||
virtual ~VP9EncodePerfTest() {}
|
virtual ~VP9EncodePerfTest() {}
|
||||||
|
|
||||||
@@ -105,13 +112,19 @@ class VP9EncodePerfTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for performance reasons don't decode
|
// for performance reasons don't decode
|
||||||
virtual bool DoDecode() const { return false; }
|
virtual bool DoDecode() { return 0; }
|
||||||
|
|
||||||
double min_psnr() const { return min_psnr_; }
|
double min_psnr() const {
|
||||||
|
return min_psnr_;
|
||||||
|
}
|
||||||
|
|
||||||
void set_speed(unsigned int speed) { speed_ = speed; }
|
void set_speed(unsigned int speed) {
|
||||||
|
speed_ = speed;
|
||||||
|
}
|
||||||
|
|
||||||
void set_threads(unsigned int threads) { threads_ = threads; }
|
void set_threads(unsigned int threads) {
|
||||||
|
threads_ = threads;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double min_psnr_;
|
double min_psnr_;
|
||||||
@@ -126,12 +139,11 @@ TEST_P(VP9EncodePerfTest, PerfTest) {
|
|||||||
for (size_t j = 0; j < NELEMENTS(kEncodePerfTestSpeeds); ++j) {
|
for (size_t j = 0; j < NELEMENTS(kEncodePerfTestSpeeds); ++j) {
|
||||||
for (size_t k = 0; k < NELEMENTS(kEncodePerfTestThreads); ++k) {
|
for (size_t k = 0; k < NELEMENTS(kEncodePerfTestThreads); ++k) {
|
||||||
if (kVP9EncodePerfTestVectors[i].width < 512 &&
|
if (kVP9EncodePerfTestVectors[i].width < 512 &&
|
||||||
kEncodePerfTestThreads[k] > 1) {
|
kEncodePerfTestThreads[k] > 1)
|
||||||
continue;
|
continue;
|
||||||
} else if (kVP9EncodePerfTestVectors[i].width < 1024 &&
|
else if (kVP9EncodePerfTestVectors[i].width < 1024 &&
|
||||||
kEncodePerfTestThreads[k] > 2) {
|
kEncodePerfTestThreads[k] > 2)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
set_threads(kEncodePerfTestThreads[k]);
|
set_threads(kEncodePerfTestThreads[k]);
|
||||||
SetUp();
|
SetUp();
|
||||||
@@ -145,8 +157,10 @@ TEST_P(VP9EncodePerfTest, PerfTest) {
|
|||||||
const unsigned frames = kVP9EncodePerfTestVectors[i].frames;
|
const unsigned frames = kVP9EncodePerfTestVectors[i].frames;
|
||||||
const char *video_name = kVP9EncodePerfTestVectors[i].name;
|
const char *video_name = kVP9EncodePerfTestVectors[i].name;
|
||||||
libvpx_test::I420VideoSource video(
|
libvpx_test::I420VideoSource video(
|
||||||
video_name, kVP9EncodePerfTestVectors[i].width,
|
video_name,
|
||||||
kVP9EncodePerfTestVectors[i].height, timebase.den, timebase.num, 0,
|
kVP9EncodePerfTestVectors[i].width,
|
||||||
|
kVP9EncodePerfTestVectors[i].height,
|
||||||
|
timebase.den, timebase.num, 0,
|
||||||
kVP9EncodePerfTestVectors[i].frames);
|
kVP9EncodePerfTestVectors[i].frames);
|
||||||
set_speed(kEncodePerfTestSpeeds[j]);
|
set_speed(kEncodePerfTestSpeeds[j]);
|
||||||
|
|
||||||
@@ -183,6 +197,6 @@ TEST_P(VP9EncodePerfTest, PerfTest) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(VP9EncodePerfTest,
|
VP10_INSTANTIATE_TEST_CASE(
|
||||||
::testing::Values(::libvpx_test::kRealTime));
|
VP9EncodePerfTest, ::testing::Values(::libvpx_test::kRealTime));
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
#include "./vpx_config.h"
|
||||||
|
#include "vpx_ports/mem.h"
|
||||||
#include "test/codec_factory.h"
|
#include "test/codec_factory.h"
|
||||||
#include "test/decode_test_driver.h"
|
#include "test/decode_test_driver.h"
|
||||||
#include "test/encode_test_driver.h"
|
#include "test/encode_test_driver.h"
|
||||||
@@ -30,39 +31,39 @@ void Encoder::InitEncoder(VideoSource *video) {
|
|||||||
cfg_.g_timebase = video->timebase();
|
cfg_.g_timebase = video->timebase();
|
||||||
cfg_.rc_twopass_stats_in = stats_->buf();
|
cfg_.rc_twopass_stats_in = stats_->buf();
|
||||||
|
|
||||||
res = vpx_codec_enc_init(&encoder_, CodecInterface(), &cfg_, init_flags_);
|
res = vpx_codec_enc_init(&encoder_, CodecInterface(), &cfg_,
|
||||||
|
init_flags_);
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
|
|
||||||
#if CONFIG_VP9_ENCODER
|
#if CONFIG_VP10_ENCODER
|
||||||
if (CodecInterface() == &vpx_codec_vp9_cx_algo) {
|
if (CodecInterface() == &vpx_codec_vp10_cx_algo) {
|
||||||
// Default to 1 tile column for VP9.
|
// Default to 1 tile column for VP10. With CONFIG_EXT_TILE, the
|
||||||
|
// default is already the largest possible tile size
|
||||||
|
#if !CONFIG_EXT_TILE
|
||||||
const int log2_tile_columns = 0;
|
const int log2_tile_columns = 0;
|
||||||
res = vpx_codec_control_(&encoder_, VP9E_SET_TILE_COLUMNS,
|
res = vpx_codec_control_(&encoder_, VP9E_SET_TILE_COLUMNS,
|
||||||
log2_tile_columns);
|
log2_tile_columns);
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
|
#endif // !CONFIG_EXT_TILE
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if CONFIG_VP8_ENCODER
|
|
||||||
ASSERT_EQ(&vpx_codec_vp8_cx_algo, CodecInterface())
|
|
||||||
<< "Unknown Codec Interface";
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Encoder::EncodeFrame(VideoSource *video, const unsigned long frame_flags) {
|
void Encoder::EncodeFrame(VideoSource *video, const unsigned long frame_flags) {
|
||||||
if (video->img()) {
|
if (video->img())
|
||||||
EncodeFrameInternal(*video, frame_flags);
|
EncodeFrameInternal(*video, frame_flags);
|
||||||
} else {
|
else
|
||||||
Flush();
|
Flush();
|
||||||
}
|
|
||||||
|
|
||||||
// Handle twopass stats
|
// Handle twopass stats
|
||||||
CxDataIterator iter = GetCxData();
|
CxDataIterator iter = GetCxData();
|
||||||
|
|
||||||
while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) {
|
while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) {
|
||||||
if (pkt->kind != VPX_CODEC_STATS_PKT) continue;
|
if (pkt->kind != VPX_CODEC_STATS_PKT)
|
||||||
|
continue;
|
||||||
|
|
||||||
stats_->Append(*pkt);
|
stats_->Append(*pkt);
|
||||||
}
|
}
|
||||||
@@ -82,15 +83,15 @@ void Encoder::EncodeFrameInternal(const VideoSource &video,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Encode the frame
|
// Encode the frame
|
||||||
API_REGISTER_STATE_CHECK(res = vpx_codec_encode(&encoder_, img, video.pts(),
|
API_REGISTER_STATE_CHECK(
|
||||||
video.duration(), frame_flags,
|
res = vpx_codec_encode(&encoder_, img, video.pts(), video.duration(),
|
||||||
deadline_));
|
frame_flags, deadline_));
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Encoder::Flush() {
|
void Encoder::Flush() {
|
||||||
const vpx_codec_err_t res =
|
const vpx_codec_err_t res = vpx_codec_encode(&encoder_, NULL, 0, 0, 0,
|
||||||
vpx_codec_encode(&encoder_, NULL, 0, 0, 0, deadline_);
|
deadline_);
|
||||||
if (!encoder_.priv)
|
if (!encoder_.priv)
|
||||||
ASSERT_EQ(VPX_CODEC_ERROR, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_ERROR, res) << EncoderError();
|
||||||
else
|
else
|
||||||
@@ -105,58 +106,143 @@ void EncoderTest::InitializeConfig() {
|
|||||||
|
|
||||||
void EncoderTest::SetMode(TestMode mode) {
|
void EncoderTest::SetMode(TestMode mode) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case kRealTime: deadline_ = VPX_DL_REALTIME; break;
|
case kRealTime:
|
||||||
|
deadline_ = VPX_DL_REALTIME;
|
||||||
|
break;
|
||||||
|
|
||||||
case kOnePassGood:
|
case kOnePassGood:
|
||||||
case kTwoPassGood: deadline_ = VPX_DL_GOOD_QUALITY; break;
|
case kTwoPassGood:
|
||||||
|
deadline_ = VPX_DL_GOOD_QUALITY;
|
||||||
|
break;
|
||||||
|
|
||||||
case kOnePassBest:
|
case kOnePassBest:
|
||||||
case kTwoPassBest: deadline_ = VPX_DL_BEST_QUALITY; break;
|
case kTwoPassBest:
|
||||||
|
deadline_ = VPX_DL_BEST_QUALITY;
|
||||||
|
break;
|
||||||
|
|
||||||
default: ASSERT_TRUE(false) << "Unexpected mode " << mode;
|
default:
|
||||||
|
ASSERT_TRUE(false) << "Unexpected mode " << mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == kTwoPassGood || mode == kTwoPassBest) {
|
if (mode == kTwoPassGood || mode == kTwoPassBest)
|
||||||
passes_ = 2;
|
passes_ = 2;
|
||||||
} else {
|
else
|
||||||
passes_ = 1;
|
passes_ = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool compare_plane(const uint8_t *const buf1, const int stride1,
|
||||||
|
const uint8_t *const buf2, const int stride2,
|
||||||
|
const int w, const int h,
|
||||||
|
int *const mismatch_row,
|
||||||
|
int *const mismatch_col,
|
||||||
|
int *const mismatch_pix1,
|
||||||
|
int *const mismatch_pix2) {
|
||||||
|
int r, c;
|
||||||
|
|
||||||
|
for (r = 0; r < h; ++r) {
|
||||||
|
for (c = 0; c < w; ++c) {
|
||||||
|
const int pix1 = buf1[r * stride1 + c];
|
||||||
|
const int pix2 = buf2[r * stride2 + c];
|
||||||
|
|
||||||
|
if (pix1 != pix2) {
|
||||||
|
if (mismatch_row != NULL)
|
||||||
|
*mismatch_row = r;
|
||||||
|
if (mismatch_col != NULL)
|
||||||
|
*mismatch_col = c;
|
||||||
|
if (mismatch_pix1 != NULL)
|
||||||
|
*mismatch_pix1 = pix1;
|
||||||
|
if (mismatch_pix2 != NULL)
|
||||||
|
*mismatch_pix2 = pix2;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// The function should return "true" most of the time, therefore no early
|
// The function should return "true" most of the time, therefore no early
|
||||||
// break-out is implemented within the match checking process.
|
// break-out is implemented within the match checking process.
|
||||||
static bool compare_img(const vpx_image_t *img1, const vpx_image_t *img2) {
|
static bool compare_img(const vpx_image_t *img1,
|
||||||
bool match = (img1->fmt == img2->fmt) && (img1->cs == img2->cs) &&
|
const vpx_image_t *img2,
|
||||||
(img1->d_w == img2->d_w) && (img1->d_h == img2->d_h);
|
int *const mismatch_row,
|
||||||
|
int *const mismatch_col,
|
||||||
|
int *const mismatch_plane,
|
||||||
|
int *const mismatch_pix1,
|
||||||
|
int *const mismatch_pix2) {
|
||||||
|
|
||||||
const unsigned int width_y = img1->d_w;
|
const unsigned int w_y = img1->d_w;
|
||||||
const unsigned int height_y = img1->d_h;
|
const unsigned int h_y = img1->d_h;
|
||||||
unsigned int i;
|
const unsigned int w_uv = ROUND_POWER_OF_TWO(w_y, img1->x_chroma_shift);
|
||||||
for (i = 0; i < height_y; ++i) {
|
const unsigned int h_uv = ROUND_POWER_OF_TWO(h_y, img1->y_chroma_shift);
|
||||||
match = (memcmp(img1->planes[VPX_PLANE_Y] + i * img1->stride[VPX_PLANE_Y],
|
|
||||||
img2->planes[VPX_PLANE_Y] + i * img2->stride[VPX_PLANE_Y],
|
if (img1->fmt != img2->fmt
|
||||||
width_y) == 0) &&
|
|| img1->cs != img2->cs
|
||||||
match;
|
|| img1->d_w != img2->d_w
|
||||||
}
|
|| img1->d_h != img2->d_h) {
|
||||||
const unsigned int width_uv = (img1->d_w + 1) >> 1;
|
if (mismatch_row != NULL)
|
||||||
const unsigned int height_uv = (img1->d_h + 1) >> 1;
|
*mismatch_row = -1;
|
||||||
for (i = 0; i < height_uv; ++i) {
|
if (mismatch_col != NULL)
|
||||||
match = (memcmp(img1->planes[VPX_PLANE_U] + i * img1->stride[VPX_PLANE_U],
|
*mismatch_col = -1;
|
||||||
img2->planes[VPX_PLANE_U] + i * img2->stride[VPX_PLANE_U],
|
return false;
|
||||||
width_uv) == 0) &&
|
|
||||||
match;
|
|
||||||
}
|
|
||||||
for (i = 0; i < height_uv; ++i) {
|
|
||||||
match = (memcmp(img1->planes[VPX_PLANE_V] + i * img1->stride[VPX_PLANE_V],
|
|
||||||
img2->planes[VPX_PLANE_V] + i * img2->stride[VPX_PLANE_V],
|
|
||||||
width_uv) == 0) &&
|
|
||||||
match;
|
|
||||||
}
|
|
||||||
return match;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncoderTest::MismatchHook(const vpx_image_t * /*img1*/,
|
if (!compare_plane(img1->planes[VPX_PLANE_Y], img1->stride[VPX_PLANE_Y],
|
||||||
const vpx_image_t * /*img2*/) {
|
img2->planes[VPX_PLANE_Y], img2->stride[VPX_PLANE_Y],
|
||||||
ASSERT_TRUE(0) << "Encode/Decode mismatch found";
|
w_y, h_y,
|
||||||
|
mismatch_row, mismatch_col,
|
||||||
|
mismatch_pix1, mismatch_pix2)) {
|
||||||
|
if (mismatch_plane != NULL)
|
||||||
|
*mismatch_plane = VPX_PLANE_Y;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!compare_plane(img1->planes[VPX_PLANE_U], img1->stride[VPX_PLANE_U],
|
||||||
|
img2->planes[VPX_PLANE_U], img2->stride[VPX_PLANE_U],
|
||||||
|
w_uv, h_uv,
|
||||||
|
mismatch_row, mismatch_col,
|
||||||
|
mismatch_pix1, mismatch_pix2)) {
|
||||||
|
if (mismatch_plane != NULL)
|
||||||
|
*mismatch_plane = VPX_PLANE_U;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!compare_plane(img1->planes[VPX_PLANE_V], img1->stride[VPX_PLANE_V],
|
||||||
|
img2->planes[VPX_PLANE_V], img2->stride[VPX_PLANE_V],
|
||||||
|
w_uv, h_uv,
|
||||||
|
mismatch_row, mismatch_col,
|
||||||
|
mismatch_pix1, mismatch_pix2)) {
|
||||||
|
if (mismatch_plane != NULL)
|
||||||
|
*mismatch_plane = VPX_PLANE_U;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EncoderTest::MismatchHook(const vpx_image_t* img_enc,
|
||||||
|
const vpx_image_t* img_dec) {
|
||||||
|
int mismatch_row = 0;
|
||||||
|
int mismatch_col = 0;
|
||||||
|
int mismatch_plane = 0;
|
||||||
|
int mismatch_pix_enc = 0;
|
||||||
|
int mismatch_pix_dec = 0;
|
||||||
|
|
||||||
|
ASSERT_FALSE(compare_img(img_enc, img_dec,
|
||||||
|
&mismatch_row, &mismatch_col,
|
||||||
|
&mismatch_plane,
|
||||||
|
&mismatch_pix_enc,
|
||||||
|
&mismatch_pix_dec));
|
||||||
|
|
||||||
|
GTEST_FAIL()
|
||||||
|
<< "Encode/Decode mismatch found:"
|
||||||
|
<< std::endl
|
||||||
|
<< " pixel value enc/dec: " << mismatch_pix_enc << "/" << mismatch_pix_dec
|
||||||
|
<< std::endl
|
||||||
|
<< " plane: " << mismatch_plane
|
||||||
|
<< std::endl
|
||||||
|
<< " row/col: " << mismatch_row << "/" << mismatch_col
|
||||||
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncoderTest::RunLoop(VideoSource *video) {
|
void EncoderTest::RunLoop(VideoSource *video) {
|
||||||
@@ -168,13 +254,12 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||||||
for (unsigned int pass = 0; pass < passes_; pass++) {
|
for (unsigned int pass = 0; pass < passes_; pass++) {
|
||||||
last_pts_ = 0;
|
last_pts_ = 0;
|
||||||
|
|
||||||
if (passes_ == 1) {
|
if (passes_ == 1)
|
||||||
cfg_.g_pass = VPX_RC_ONE_PASS;
|
cfg_.g_pass = VPX_RC_ONE_PASS;
|
||||||
} else if (pass == 0) {
|
else if (pass == 0)
|
||||||
cfg_.g_pass = VPX_RC_FIRST_PASS;
|
cfg_.g_pass = VPX_RC_FIRST_PASS;
|
||||||
} else {
|
else
|
||||||
cfg_.g_pass = VPX_RC_LAST_PASS;
|
cfg_.g_pass = VPX_RC_LAST_PASS;
|
||||||
}
|
|
||||||
|
|
||||||
BeginPassHook(pass);
|
BeginPassHook(pass);
|
||||||
testing::internal::scoped_ptr<Encoder> encoder(
|
testing::internal::scoped_ptr<Encoder> encoder(
|
||||||
@@ -188,11 +273,19 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||||||
unsigned long dec_init_flags = 0; // NOLINT
|
unsigned long dec_init_flags = 0; // NOLINT
|
||||||
// Use fragment decoder if encoder outputs partitions.
|
// Use fragment decoder if encoder outputs partitions.
|
||||||
// NOTE: fragment decoder and partition encoder are only supported by VP8.
|
// NOTE: fragment decoder and partition encoder are only supported by VP8.
|
||||||
if (init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) {
|
if (init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION)
|
||||||
dec_init_flags |= VPX_CODEC_USE_INPUT_FRAGMENTS;
|
dec_init_flags |= VPX_CODEC_USE_INPUT_FRAGMENTS;
|
||||||
}
|
|
||||||
testing::internal::scoped_ptr<Decoder> decoder(
|
testing::internal::scoped_ptr<Decoder> decoder(
|
||||||
codec_->CreateDecoder(dec_cfg, dec_init_flags));
|
codec_->CreateDecoder(dec_cfg, dec_init_flags, 0));
|
||||||
|
#if CONFIG_VP10 && CONFIG_EXT_TILE
|
||||||
|
if (decoder->IsVP10()) {
|
||||||
|
// Set dec_cfg.tile_row = -1 and dec_cfg.tile_col = -1 so that the whole
|
||||||
|
// frame is decoded.
|
||||||
|
decoder->Control(VP10_SET_DECODE_TILE_ROW, -1);
|
||||||
|
decoder->Control(VP10_SET_DECODE_TILE_COL, -1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool again;
|
bool again;
|
||||||
for (again = true; again; video->Next()) {
|
for (again = true; again; video->Next()) {
|
||||||
again = (video->img() != NULL);
|
again = (video->img() != NULL);
|
||||||
@@ -201,8 +294,6 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||||||
PreEncodeFrameHook(video, encoder.get());
|
PreEncodeFrameHook(video, encoder.get());
|
||||||
encoder->EncodeFrame(video, frame_flags_);
|
encoder->EncodeFrame(video, frame_flags_);
|
||||||
|
|
||||||
PostEncodeFrameHook(encoder.get());
|
|
||||||
|
|
||||||
CxDataIterator iter = encoder->GetCxData();
|
CxDataIterator iter = encoder->GetCxData();
|
||||||
|
|
||||||
bool has_cxdata = false;
|
bool has_cxdata = false;
|
||||||
@@ -217,7 +308,8 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||||||
vpx_codec_err_t res_dec = decoder->DecodeFrame(
|
vpx_codec_err_t res_dec = decoder->DecodeFrame(
|
||||||
(const uint8_t*)pkt->data.frame.buf, pkt->data.frame.sz);
|
(const uint8_t*)pkt->data.frame.buf, pkt->data.frame.sz);
|
||||||
|
|
||||||
if (!HandleDecodeResult(res_dec, *video, decoder.get())) break;
|
if (!HandleDecodeResult(res_dec, *video, decoder.get()))
|
||||||
|
break;
|
||||||
|
|
||||||
has_dxdata = true;
|
has_dxdata = true;
|
||||||
}
|
}
|
||||||
@@ -226,18 +318,20 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||||||
FramePktHook(pkt);
|
FramePktHook(pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VPX_CODEC_PSNR_PKT: PSNRPktHook(pkt); break;
|
case VPX_CODEC_PSNR_PKT:
|
||||||
|
PSNRPktHook(pkt);
|
||||||
|
break;
|
||||||
|
|
||||||
case VPX_CODEC_STATS_PKT: StatsPktHook(pkt); break;
|
default:
|
||||||
|
break;
|
||||||
default: break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush the decoder when there are no more fragments.
|
// Flush the decoder when there are no more fragments.
|
||||||
if ((init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) && has_dxdata) {
|
if ((init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) && has_dxdata) {
|
||||||
const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0);
|
const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0);
|
||||||
if (!HandleDecodeResult(res_dec, *video, decoder.get())) break;
|
if (!HandleDecodeResult(res_dec, *video, decoder.get()))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_dxdata && has_cxdata) {
|
if (has_dxdata && has_cxdata) {
|
||||||
@@ -245,19 +339,23 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||||||
DxDataIterator dec_iter = decoder->GetDxData();
|
DxDataIterator dec_iter = decoder->GetDxData();
|
||||||
const vpx_image_t *img_dec = dec_iter.Next();
|
const vpx_image_t *img_dec = dec_iter.Next();
|
||||||
if (img_enc && img_dec) {
|
if (img_enc && img_dec) {
|
||||||
const bool res = compare_img(img_enc, img_dec);
|
const bool res = compare_img(img_enc, img_dec,
|
||||||
|
NULL, NULL, NULL, NULL, NULL);
|
||||||
if (!res) { // Mismatch
|
if (!res) { // Mismatch
|
||||||
MismatchHook(img_enc, img_dec);
|
MismatchHook(img_enc, img_dec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (img_dec) DecompressedFrameHook(*img_dec, video->pts());
|
if (img_dec)
|
||||||
|
DecompressedFrameHook(*img_dec, video->pts());
|
||||||
}
|
}
|
||||||
if (!Continue()) break;
|
if (!Continue())
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
EndPassHook();
|
EndPassHook();
|
||||||
|
|
||||||
if (!Continue()) break;
|
if (!Continue())
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
#include "./vpx_config.h"
|
||||||
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
|
#if CONFIG_VP10_ENCODER
|
||||||
#include "vpx/vp8cx.h"
|
#include "vpx/vp8cx.h"
|
||||||
#endif
|
#endif
|
||||||
#include "vpx/vpx_encoder.h"
|
#include "vpx/vpx_encoder.h"
|
||||||
@@ -33,17 +33,19 @@ enum TestMode {
|
|||||||
kTwoPassGood,
|
kTwoPassGood,
|
||||||
kTwoPassBest
|
kTwoPassBest
|
||||||
};
|
};
|
||||||
#define ALL_TEST_MODES \
|
#define ALL_TEST_MODES ::testing::Values(::libvpx_test::kRealTime, \
|
||||||
::testing::Values(::libvpx_test::kRealTime, ::libvpx_test::kOnePassGood, \
|
::libvpx_test::kOnePassGood, \
|
||||||
::libvpx_test::kOnePassBest, ::libvpx_test::kTwoPassGood, \
|
::libvpx_test::kOnePassBest, \
|
||||||
|
::libvpx_test::kTwoPassGood, \
|
||||||
::libvpx_test::kTwoPassBest)
|
::libvpx_test::kTwoPassBest)
|
||||||
|
|
||||||
#define ONE_PASS_TEST_MODES \
|
#define ONE_PASS_TEST_MODES ::testing::Values(::libvpx_test::kRealTime, \
|
||||||
::testing::Values(::libvpx_test::kRealTime, ::libvpx_test::kOnePassGood, \
|
::libvpx_test::kOnePassGood, \
|
||||||
::libvpx_test::kOnePassBest)
|
::libvpx_test::kOnePassBest)
|
||||||
|
|
||||||
#define TWO_PASS_TEST_MODES \
|
#define TWO_PASS_TEST_MODES ::testing::Values(::libvpx_test::kTwoPassGood, \
|
||||||
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kTwoPassBest)
|
::libvpx_test::kTwoPassBest)
|
||||||
|
|
||||||
|
|
||||||
// Provides an object to handle the libvpx get_cx_data() iteration pattern
|
// Provides an object to handle the libvpx get_cx_data() iteration pattern
|
||||||
class CxDataIterator {
|
class CxDataIterator {
|
||||||
@@ -73,12 +75,15 @@ class TwopassStatsStore {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() { buffer_.clear(); }
|
void Reset() {
|
||||||
|
buffer_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string buffer_;
|
std::string buffer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Provides a simplified interface to manage one video encoding pass, given
|
// Provides a simplified interface to manage one video encoding pass, given
|
||||||
// a configuration and video source.
|
// a configuration and video source.
|
||||||
//
|
//
|
||||||
@@ -92,9 +97,13 @@ class Encoder {
|
|||||||
memset(&encoder_, 0, sizeof(encoder_));
|
memset(&encoder_, 0, sizeof(encoder_));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Encoder() { vpx_codec_destroy(&encoder_); }
|
virtual ~Encoder() {
|
||||||
|
vpx_codec_destroy(&encoder_);
|
||||||
|
}
|
||||||
|
|
||||||
CxDataIterator GetCxData() { return CxDataIterator(&encoder_); }
|
CxDataIterator GetCxData() {
|
||||||
|
return CxDataIterator(&encoder_);
|
||||||
|
}
|
||||||
|
|
||||||
void InitEncoder(VideoSource *video);
|
void InitEncoder(VideoSource *video);
|
||||||
|
|
||||||
@@ -106,7 +115,9 @@ class Encoder {
|
|||||||
void EncodeFrame(VideoSource *video, const unsigned long frame_flags);
|
void EncodeFrame(VideoSource *video, const unsigned long frame_flags);
|
||||||
|
|
||||||
// Convenience wrapper for EncodeFrame()
|
// Convenience wrapper for EncodeFrame()
|
||||||
void EncodeFrame(VideoSource *video) { EncodeFrame(video, 0); }
|
void EncodeFrame(VideoSource *video) {
|
||||||
|
EncodeFrame(video, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void Control(int ctrl_id, int arg) {
|
void Control(int ctrl_id, int arg) {
|
||||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||||
@@ -132,27 +143,22 @@ class Encoder {
|
|||||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
}
|
}
|
||||||
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
|
#if CONFIG_VP10_ENCODER
|
||||||
void Control(int ctrl_id, vpx_active_map_t *arg) {
|
void Control(int ctrl_id, vpx_active_map_t *arg) {
|
||||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_VP8_ENCODER
|
|
||||||
void Control(int ctrl_id, vpx_roi_map_t *arg) {
|
|
||||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Config(const vpx_codec_enc_cfg_t *cfg) {
|
void Config(const vpx_codec_enc_cfg_t *cfg) {
|
||||||
const vpx_codec_err_t res = vpx_codec_enc_config_set(&encoder_, cfg);
|
const vpx_codec_err_t res = vpx_codec_enc_config_set(&encoder_, cfg);
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
cfg_ = *cfg;
|
cfg_ = *cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_deadline(unsigned long deadline) { deadline_ = deadline; }
|
void set_deadline(unsigned long deadline) {
|
||||||
|
deadline_ = deadline;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual vpx_codec_iface_t* CodecInterface() const = 0;
|
virtual vpx_codec_iface_t* CodecInterface() const = 0;
|
||||||
@@ -219,17 +225,12 @@ class EncoderTest {
|
|||||||
virtual void PreEncodeFrameHook(VideoSource* /*video*/,
|
virtual void PreEncodeFrameHook(VideoSource* /*video*/,
|
||||||
Encoder* /*encoder*/) {}
|
Encoder* /*encoder*/) {}
|
||||||
|
|
||||||
virtual void PostEncodeFrameHook(Encoder * /*encoder*/) {}
|
|
||||||
|
|
||||||
// Hook to be called on every compressed data packet.
|
// Hook to be called on every compressed data packet.
|
||||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t* /*pkt*/) {}
|
virtual void FramePktHook(const vpx_codec_cx_pkt_t* /*pkt*/) {}
|
||||||
|
|
||||||
// Hook to be called on every PSNR packet.
|
// Hook to be called on every PSNR packet.
|
||||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t* /*pkt*/) {}
|
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t* /*pkt*/) {}
|
||||||
|
|
||||||
// Hook to be called on every first pass stats packet.
|
|
||||||
virtual void StatsPktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {}
|
|
||||||
|
|
||||||
// Hook to determine whether the encode loop should continue.
|
// Hook to determine whether the encode loop should continue.
|
||||||
virtual bool Continue() const {
|
virtual bool Continue() const {
|
||||||
return !(::testing::Test::HasFatalFailure() || abort_);
|
return !(::testing::Test::HasFatalFailure() || abort_);
|
||||||
@@ -240,7 +241,8 @@ class EncoderTest {
|
|||||||
virtual bool DoDecode() const { return 1; }
|
virtual bool DoDecode() const { return 1; }
|
||||||
|
|
||||||
// Hook to handle encode/decode mismatch
|
// Hook to handle encode/decode mismatch
|
||||||
virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2);
|
virtual void MismatchHook(const vpx_image_t *img1,
|
||||||
|
const vpx_image_t *img2);
|
||||||
|
|
||||||
// Hook to be called on every decompressed frame.
|
// Hook to be called on every decompressed frame.
|
||||||
virtual void DecompressedFrameHook(const vpx_image_t& /*img*/,
|
virtual void DecompressedFrameHook(const vpx_image_t& /*img*/,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#include "test/encode_test_driver.h"
|
#include "test/encode_test_driver.h"
|
||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
#include "test/y4m_video_source.h"
|
#include "test/y4m_video_source.h"
|
||||||
#include "vp9/vp9_dx_iface.h"
|
#include "vp10/vp10_dx_iface.c"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@@ -87,11 +87,10 @@ class VpxEncoderParmsGetToDecoder
|
|||||||
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
||||||
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
|
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
|
||||||
encoder->Control(VP8E_SET_ARNR_TYPE, 3);
|
encoder->Control(VP8E_SET_ARNR_TYPE, 3);
|
||||||
if (encode_parms.render_size[0] > 0 && encode_parms.render_size[1] > 0) {
|
if (encode_parms.render_size[0] > 0 && encode_parms.render_size[1] > 0)
|
||||||
encoder->Control(VP9E_SET_RENDER_SIZE, encode_parms.render_size);
|
encoder->Control(VP9E_SET_RENDER_SIZE, encode_parms.render_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec,
|
virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec,
|
||||||
const libvpx_test::VideoSource & /*video*/,
|
const libvpx_test::VideoSource & /*video*/,
|
||||||
@@ -99,7 +98,9 @@ class VpxEncoderParmsGetToDecoder
|
|||||||
vpx_codec_ctx_t *const vp9_decoder = decoder->GetDecoder();
|
vpx_codec_ctx_t *const vp9_decoder = decoder->GetDecoder();
|
||||||
vpx_codec_alg_priv_t *const priv =
|
vpx_codec_alg_priv_t *const priv =
|
||||||
reinterpret_cast<vpx_codec_alg_priv_t *>(vp9_decoder->priv);
|
reinterpret_cast<vpx_codec_alg_priv_t *>(vp9_decoder->priv);
|
||||||
VP9_COMMON *const common = &priv->pbi->common;
|
FrameWorkerData *const worker_data =
|
||||||
|
reinterpret_cast<FrameWorkerData *>(priv->frame_workers[0].data1);
|
||||||
|
VP10_COMMON *const common = &worker_data->pbi->common;
|
||||||
|
|
||||||
if (encode_parms.lossless) {
|
if (encode_parms.lossless) {
|
||||||
EXPECT_EQ(0, common->base_qindex);
|
EXPECT_EQ(0, common->base_qindex);
|
||||||
@@ -110,11 +111,7 @@ class VpxEncoderParmsGetToDecoder
|
|||||||
}
|
}
|
||||||
EXPECT_EQ(encode_parms.error_resilient, common->error_resilient_mode);
|
EXPECT_EQ(encode_parms.error_resilient, common->error_resilient_mode);
|
||||||
if (encode_parms.error_resilient) {
|
if (encode_parms.error_resilient) {
|
||||||
EXPECT_EQ(1, common->frame_parallel_decoding_mode);
|
|
||||||
EXPECT_EQ(0, common->use_prev_frame_mvs);
|
EXPECT_EQ(0, common->use_prev_frame_mvs);
|
||||||
} else {
|
|
||||||
EXPECT_EQ(encode_parms.frame_parallel,
|
|
||||||
common->frame_parallel_decoding_mode);
|
|
||||||
}
|
}
|
||||||
EXPECT_EQ(encode_parms.color_range, common->color_range);
|
EXPECT_EQ(encode_parms.color_range, common->color_range);
|
||||||
EXPECT_EQ(encode_parms.cs, common->color_space);
|
EXPECT_EQ(encode_parms.cs, common->color_space);
|
||||||
@@ -138,14 +135,15 @@ class VpxEncoderParmsGetToDecoder
|
|||||||
TEST_P(VpxEncoderParmsGetToDecoder, BitstreamParms) {
|
TEST_P(VpxEncoderParmsGetToDecoder, BitstreamParms) {
|
||||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||||
|
|
||||||
testing::internal::scoped_ptr<libvpx_test::VideoSource> video(
|
libvpx_test::VideoSource *const video =
|
||||||
new libvpx_test::Y4mVideoSource(test_video_.name, 0, test_video_.frames));
|
new libvpx_test::Y4mVideoSource(test_video_.name, 0, test_video_.frames);
|
||||||
ASSERT_TRUE(video.get() != NULL);
|
ASSERT_TRUE(video != NULL);
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(video));
|
||||||
|
delete video;
|
||||||
}
|
}
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(VpxEncoderParmsGetToDecoder,
|
VP10_INSTANTIATE_TEST_CASE(VpxEncoderParmsGetToDecoder,
|
||||||
::testing::ValuesIn(kVP9EncodeParameterSet),
|
::testing::ValuesIn(kVP9EncodeParameterSet),
|
||||||
::testing::ValuesIn(kVP9EncodePerfTestVectors));
|
::testing::ValuesIn(kVP9EncodePerfTestVectors));
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -25,10 +25,29 @@ const unsigned int kFrames = 10;
|
|||||||
const int kBitrate = 500;
|
const int kBitrate = 500;
|
||||||
// List of psnr thresholds for speed settings 0-7 and 5 encoding modes
|
// List of psnr thresholds for speed settings 0-7 and 5 encoding modes
|
||||||
const double kPsnrThreshold[][5] = {
|
const double kPsnrThreshold[][5] = {
|
||||||
{ 36.0, 37.0, 37.0, 37.0, 37.0 }, { 35.0, 36.0, 36.0, 36.0, 36.0 },
|
// Note:
|
||||||
{ 34.0, 35.0, 35.0, 35.0, 35.0 }, { 33.0, 34.0, 34.0, 34.0, 34.0 },
|
// VP10 HBD average PSNR is slightly lower than VP9.
|
||||||
{ 32.0, 33.0, 33.0, 33.0, 33.0 }, { 31.0, 32.0, 32.0, 32.0, 32.0 },
|
// We make two cases here to enable the testing and
|
||||||
{ 30.0, 31.0, 31.0, 31.0, 31.0 }, { 29.0, 30.0, 30.0, 30.0, 30.0 },
|
// guard picture quality.
|
||||||
|
#if CONFIG_VP10_ENCODER && CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
{ 36.0, 37.0, 37.0, 37.0, 37.0 },
|
||||||
|
{ 31.0, 36.0, 36.0, 36.0, 36.0 },
|
||||||
|
{ 31.0, 35.0, 35.0, 35.0, 35.0 },
|
||||||
|
{ 31.0, 34.0, 34.0, 34.0, 34.0 },
|
||||||
|
{ 31.0, 33.0, 33.0, 33.0, 33.0 },
|
||||||
|
{ 31.0, 32.0, 32.0, 32.0, 32.0 },
|
||||||
|
{ 30.0, 31.0, 31.0, 31.0, 31.0 },
|
||||||
|
{ 29.0, 30.0, 30.0, 30.0, 30.0 },
|
||||||
|
#else
|
||||||
|
{ 36.0, 37.0, 37.0, 37.0, 37.0 },
|
||||||
|
{ 35.0, 36.0, 36.0, 36.0, 36.0 },
|
||||||
|
{ 34.0, 35.0, 35.0, 35.0, 35.0 },
|
||||||
|
{ 33.0, 34.0, 34.0, 34.0, 34.0 },
|
||||||
|
{ 32.0, 33.0, 33.0, 33.0, 33.0 },
|
||||||
|
{ 31.0, 32.0, 32.0, 32.0, 32.0 },
|
||||||
|
{ 30.0, 31.0, 31.0, 31.0, 31.0 },
|
||||||
|
{ 29.0, 30.0, 30.0, 30.0, 30.0 },
|
||||||
|
#endif // CONFIG_VPX_HIGHBITDEPTH && CONFIG_VP10_ENCODER
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -44,7 +63,7 @@ const TestVideoParam kTestVectors[] = {
|
|||||||
{"park_joy_90p_8_422.y4m", 8, VPX_IMG_FMT_I422, VPX_BITS_8, 1},
|
{"park_joy_90p_8_422.y4m", 8, VPX_IMG_FMT_I422, VPX_BITS_8, 1},
|
||||||
{"park_joy_90p_8_444.y4m", 8, VPX_IMG_FMT_I444, VPX_BITS_8, 1},
|
{"park_joy_90p_8_444.y4m", 8, VPX_IMG_FMT_I444, VPX_BITS_8, 1},
|
||||||
{"park_joy_90p_8_440.yuv", 8, VPX_IMG_FMT_I440, VPX_BITS_8, 1},
|
{"park_joy_90p_8_440.yuv", 8, VPX_IMG_FMT_I440, VPX_BITS_8, 1},
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
{"park_joy_90p_10_420.y4m", 10, VPX_IMG_FMT_I42016, VPX_BITS_10, 2},
|
{"park_joy_90p_10_420.y4m", 10, VPX_IMG_FMT_I42016, VPX_BITS_10, 2},
|
||||||
{"park_joy_90p_10_422.y4m", 10, VPX_IMG_FMT_I42216, VPX_BITS_10, 3},
|
{"park_joy_90p_10_422.y4m", 10, VPX_IMG_FMT_I42216, VPX_BITS_10, 3},
|
||||||
{"park_joy_90p_10_444.y4m", 10, VPX_IMG_FMT_I44416, VPX_BITS_10, 3},
|
{"park_joy_90p_10_444.y4m", 10, VPX_IMG_FMT_I44416, VPX_BITS_10, 3},
|
||||||
@@ -53,12 +72,13 @@ const TestVideoParam kTestVectors[] = {
|
|||||||
{"park_joy_90p_12_422.y4m", 12, VPX_IMG_FMT_I42216, VPX_BITS_12, 3},
|
{"park_joy_90p_12_422.y4m", 12, VPX_IMG_FMT_I42216, VPX_BITS_12, 3},
|
||||||
{"park_joy_90p_12_444.y4m", 12, VPX_IMG_FMT_I44416, VPX_BITS_12, 3},
|
{"park_joy_90p_12_444.y4m", 12, VPX_IMG_FMT_I44416, VPX_BITS_12, 3},
|
||||||
{"park_joy_90p_12_440.yuv", 12, VPX_IMG_FMT_I44016, VPX_BITS_12, 3},
|
{"park_joy_90p_12_440.yuv", 12, VPX_IMG_FMT_I44016, VPX_BITS_12, 3},
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
};
|
};
|
||||||
|
|
||||||
// Encoding modes tested
|
// Encoding modes tested
|
||||||
const libvpx_test::TestMode kEncodingModeVectors[] = {
|
const libvpx_test::TestMode kEncodingModeVectors[] = {
|
||||||
::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood,
|
::libvpx_test::kTwoPassGood,
|
||||||
|
::libvpx_test::kOnePassGood,
|
||||||
::libvpx_test::kRealTime,
|
::libvpx_test::kRealTime,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -67,22 +87,25 @@ const int kCpuUsedVectors[] = { 1, 2, 3, 5, 6 };
|
|||||||
|
|
||||||
int is_extension_y4m(const char *filename) {
|
int is_extension_y4m(const char *filename) {
|
||||||
const char *dot = strrchr(filename, '.');
|
const char *dot = strrchr(filename, '.');
|
||||||
if (!dot || dot == filename) {
|
if (!dot || dot == filename)
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
else
|
||||||
return !strcmp(dot, ".y4m");
|
return !strcmp(dot, ".y4m");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class EndToEndTestLarge
|
class EndToEndTestLarge
|
||||||
: public ::libvpx_test::EncoderTest,
|
: public ::libvpx_test::EncoderTest,
|
||||||
public ::libvpx_test::CodecTestWith3Params<libvpx_test::TestMode,
|
public ::libvpx_test::CodecTestWith3Params<libvpx_test::TestMode, \
|
||||||
TestVideoParam, int> {
|
TestVideoParam, int> {
|
||||||
protected:
|
protected:
|
||||||
EndToEndTestLarge()
|
EndToEndTestLarge()
|
||||||
: EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(2)),
|
: EncoderTest(GET_PARAM(0)),
|
||||||
cpu_used_(GET_PARAM(3)), psnr_(0.0), nframes_(0),
|
test_video_param_(GET_PARAM(2)),
|
||||||
encoding_mode_(GET_PARAM(1)) {}
|
cpu_used_(GET_PARAM(3)),
|
||||||
|
psnr_(0.0),
|
||||||
|
nframes_(0),
|
||||||
|
encoding_mode_(GET_PARAM(1)) {
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~EndToEndTestLarge() {}
|
virtual ~EndToEndTestLarge() {}
|
||||||
|
|
||||||
@@ -118,6 +141,11 @@ class EndToEndTestLarge
|
|||||||
encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1);
|
encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1);
|
||||||
encoder->Control(VP9E_SET_TILE_COLUMNS, 4);
|
encoder->Control(VP9E_SET_TILE_COLUMNS, 4);
|
||||||
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
||||||
|
// Test screen coding tools at cpu_used = 1 && encoding mode is two-pass.
|
||||||
|
if (cpu_used_ == 1 && encoding_mode_ == ::libvpx_test::kTwoPassGood)
|
||||||
|
encoder->Control(VP9E_SET_TUNE_CONTENT, VPX_CONTENT_SCREEN);
|
||||||
|
else
|
||||||
|
encoder->Control(VP9E_SET_TUNE_CONTENT, VPX_CONTENT_DEFAULT);
|
||||||
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
||||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||||
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
||||||
@@ -128,7 +156,8 @@ class EndToEndTestLarge
|
|||||||
}
|
}
|
||||||
|
|
||||||
double GetAveragePsnr() const {
|
double GetAveragePsnr() const {
|
||||||
if (nframes_) return psnr_ / nframes_;
|
if (nframes_)
|
||||||
|
return psnr_ / nframes_;
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,25 +181,29 @@ TEST_P(EndToEndTestLarge, EndtoEndPSNRTest) {
|
|||||||
cfg_.g_input_bit_depth = test_video_param_.input_bit_depth;
|
cfg_.g_input_bit_depth = test_video_param_.input_bit_depth;
|
||||||
cfg_.g_bit_depth = test_video_param_.bit_depth;
|
cfg_.g_bit_depth = test_video_param_.bit_depth;
|
||||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||||
if (cfg_.g_bit_depth > 8) init_flags_ |= VPX_CODEC_USE_HIGHBITDEPTH;
|
if (cfg_.g_bit_depth > 8)
|
||||||
|
init_flags_ |= VPX_CODEC_USE_HIGHBITDEPTH;
|
||||||
|
|
||||||
testing::internal::scoped_ptr<libvpx_test::VideoSource> video;
|
libvpx_test::VideoSource *video;
|
||||||
if (is_extension_y4m(test_video_param_.filename)) {
|
if (is_extension_y4m(test_video_param_.filename)) {
|
||||||
video.reset(new libvpx_test::Y4mVideoSource(test_video_param_.filename, 0,
|
video = new libvpx_test::Y4mVideoSource(test_video_param_.filename,
|
||||||
kFrames));
|
0, kFrames);
|
||||||
} else {
|
} else {
|
||||||
video.reset(new libvpx_test::YUVVideoSource(
|
video = new libvpx_test::YUVVideoSource(test_video_param_.filename,
|
||||||
test_video_param_.filename, test_video_param_.fmt, kWidth, kHeight,
|
test_video_param_.fmt,
|
||||||
kFramerate, 1, 0, kFrames));
|
kWidth, kHeight,
|
||||||
|
kFramerate, 1, 0, kFrames);
|
||||||
}
|
}
|
||||||
ASSERT_TRUE(video.get() != NULL);
|
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(video));
|
||||||
const double psnr = GetAveragePsnr();
|
const double psnr = GetAveragePsnr();
|
||||||
EXPECT_GT(psnr, GetPsnrThreshold());
|
EXPECT_GT(psnr, GetPsnrThreshold());
|
||||||
|
delete(video);
|
||||||
}
|
}
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(EndToEndTestLarge,
|
|
||||||
|
VP10_INSTANTIATE_TEST_CASE(
|
||||||
|
EndToEndTestLarge,
|
||||||
::testing::ValuesIn(kEncodingModeVectors),
|
::testing::ValuesIn(kEncodingModeVectors),
|
||||||
::testing::ValuesIn(kTestVectors),
|
::testing::ValuesIn(kTestVectors),
|
||||||
::testing::ValuesIn(kCpuUsedVectors));
|
::testing::ValuesIn(kCpuUsedVectors));
|
||||||
@@ -15,44 +15,33 @@
|
|||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
#include "./vpx_config.h"
|
||||||
#include "./vp9_rtcd.h"
|
#include "./vp10_rtcd.h"
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
#include "vp9/common/vp9_entropy.h"
|
#include "vp10/common/entropy.h"
|
||||||
#include "vpx/vpx_codec.h"
|
#include "vpx/vpx_codec.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
#include "vpx_dsp/vpx_dsp_common.h"
|
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
const int kNumIterations = 1000;
|
const int kNumIterations = 1000;
|
||||||
|
|
||||||
typedef int64_t (*HBDBlockErrorFunc)(const tran_low_t *coeff,
|
typedef int64_t (*ErrorBlockFunc)(const tran_low_t *coeff,
|
||||||
const tran_low_t *dqcoeff,
|
const tran_low_t *dqcoeff,
|
||||||
intptr_t block_size, int64_t *ssz,
|
intptr_t block_size,
|
||||||
int bps);
|
int64_t *ssz, int bps);
|
||||||
|
|
||||||
typedef std::tr1::tuple<HBDBlockErrorFunc, HBDBlockErrorFunc, vpx_bit_depth_t>
|
typedef std::tr1::tuple<ErrorBlockFunc, ErrorBlockFunc, vpx_bit_depth_t>
|
||||||
BlockErrorParam;
|
ErrorBlockParam;
|
||||||
|
|
||||||
typedef int64_t (*BlockErrorFunc)(const tran_low_t *coeff,
|
class ErrorBlockTest
|
||||||
const tran_low_t *dqcoeff,
|
: public ::testing::TestWithParam<ErrorBlockParam> {
|
||||||
intptr_t block_size, int64_t *ssz);
|
|
||||||
|
|
||||||
template <BlockErrorFunc fn>
|
|
||||||
int64_t BlockError8BitWrapper(const tran_low_t *coeff,
|
|
||||||
const tran_low_t *dqcoeff, intptr_t block_size,
|
|
||||||
int64_t *ssz, int bps) {
|
|
||||||
EXPECT_EQ(bps, 8);
|
|
||||||
return fn(coeff, dqcoeff, block_size, ssz);
|
|
||||||
}
|
|
||||||
|
|
||||||
class BlockErrorTest : public ::testing::TestWithParam<BlockErrorParam> {
|
|
||||||
public:
|
public:
|
||||||
virtual ~BlockErrorTest() {}
|
virtual ~ErrorBlockTest() {}
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
error_block_op_ = GET_PARAM(0);
|
error_block_op_ = GET_PARAM(0);
|
||||||
ref_error_block_op_ = GET_PARAM(1);
|
ref_error_block_op_ = GET_PARAM(1);
|
||||||
@@ -63,11 +52,11 @@ class BlockErrorTest : public ::testing::TestWithParam<BlockErrorParam> {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
vpx_bit_depth_t bit_depth_;
|
vpx_bit_depth_t bit_depth_;
|
||||||
HBDBlockErrorFunc error_block_op_;
|
ErrorBlockFunc error_block_op_;
|
||||||
HBDBlockErrorFunc ref_error_block_op_;
|
ErrorBlockFunc ref_error_block_op_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(BlockErrorTest, OperationCheck) {
|
TEST_P(ErrorBlockTest, OperationCheck) {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
DECLARE_ALIGNED(16, tran_low_t, coeff[4096]);
|
DECLARE_ALIGNED(16, tran_low_t, coeff[4096]);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]);
|
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]);
|
||||||
@@ -95,10 +84,10 @@ TEST_P(BlockErrorTest, OperationCheck) {
|
|||||||
dqcoeff[j] = -rnd(1 << msb);
|
dqcoeff[j] = -rnd(1 << msb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ref_ret =
|
ref_ret = ref_error_block_op_(coeff, dqcoeff, block_size, &ref_ssz,
|
||||||
ref_error_block_op_(coeff, dqcoeff, block_size, &ref_ssz, bit_depth_);
|
bit_depth_);
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(ret = error_block_op_(coeff, dqcoeff, block_size,
|
||||||
ret = error_block_op_(coeff, dqcoeff, block_size, &ssz, bit_depth_));
|
&ssz, bit_depth_));
|
||||||
err_count += (ref_ret != ret) | (ref_ssz != ssz);
|
err_count += (ref_ret != ret) | (ref_ssz != ssz);
|
||||||
if (err_count && !err_count_total) {
|
if (err_count && !err_count_total) {
|
||||||
first_failure = i;
|
first_failure = i;
|
||||||
@@ -110,7 +99,7 @@ TEST_P(BlockErrorTest, OperationCheck) {
|
|||||||
<< "First failed at test case " << first_failure;
|
<< "First failed at test case " << first_failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(BlockErrorTest, ExtremeValues) {
|
TEST_P(ErrorBlockTest, ExtremeValues) {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
DECLARE_ALIGNED(16, tran_low_t, coeff[4096]);
|
DECLARE_ALIGNED(16, tran_low_t, coeff[4096]);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]);
|
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]);
|
||||||
@@ -153,10 +142,10 @@ TEST_P(BlockErrorTest, ExtremeValues) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ref_ret =
|
ref_ret = ref_error_block_op_(coeff, dqcoeff, block_size, &ref_ssz,
|
||||||
ref_error_block_op_(coeff, dqcoeff, block_size, &ref_ssz, bit_depth_);
|
bit_depth_);
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(ret = error_block_op_(coeff, dqcoeff, block_size,
|
||||||
ret = error_block_op_(coeff, dqcoeff, block_size, &ssz, bit_depth_));
|
&ssz, bit_depth_));
|
||||||
err_count += (ref_ret != ret) | (ref_ssz != ssz);
|
err_count += (ref_ret != ret) | (ref_ssz != ssz);
|
||||||
if (err_count && !err_count_total) {
|
if (err_count && !err_count_total) {
|
||||||
first_failure = i;
|
first_failure = i;
|
||||||
@@ -168,31 +157,19 @@ TEST_P(BlockErrorTest, ExtremeValues) {
|
|||||||
<< "First failed at test case " << first_failure;
|
<< "First failed at test case " << first_failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAVE_SSE2 || HAVE_AVX
|
||||||
using std::tr1::make_tuple;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
#if HAVE_SSE2
|
INSTANTIATE_TEST_CASE_P(
|
||||||
const BlockErrorParam sse2_block_error_tests[] = {
|
SSE2, ErrorBlockTest,
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
::testing::Values(
|
||||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
make_tuple(&vp10_highbd_block_error_sse2,
|
||||||
VPX_BITS_10),
|
&vp10_highbd_block_error_c, VPX_BITS_10),
|
||||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
make_tuple(&vp10_highbd_block_error_sse2,
|
||||||
VPX_BITS_12),
|
&vp10_highbd_block_error_c, VPX_BITS_12),
|
||||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
make_tuple(&vp10_highbd_block_error_sse2,
|
||||||
VPX_BITS_8),
|
&vp10_highbd_block_error_c, VPX_BITS_8)));
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
make_tuple(&BlockError8BitWrapper<vp9_block_error_sse2>,
|
|
||||||
&BlockError8BitWrapper<vp9_block_error_c>, VPX_BITS_8)
|
|
||||||
};
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, BlockErrorTest,
|
|
||||||
::testing::ValuesIn(sse2_block_error_tests));
|
|
||||||
#endif // HAVE_SSE2
|
#endif // HAVE_SSE2
|
||||||
|
|
||||||
#if HAVE_AVX2
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
AVX2, BlockErrorTest,
|
|
||||||
::testing::Values(make_tuple(&BlockError8BitWrapper<vp9_block_error_avx2>,
|
|
||||||
&BlockError8BitWrapper<vp9_block_error_c>,
|
|
||||||
VPX_BITS_8)));
|
|
||||||
#endif // HAVE_AVX2
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -19,13 +19,16 @@ namespace {
|
|||||||
const int kMaxErrorFrames = 12;
|
const int kMaxErrorFrames = 12;
|
||||||
const int kMaxDroppableFrames = 12;
|
const int kMaxDroppableFrames = 12;
|
||||||
|
|
||||||
class ErrorResilienceTestLarge
|
class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
|
||||||
: public ::libvpx_test::EncoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, bool> {
|
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, bool> {
|
||||||
protected:
|
protected:
|
||||||
ErrorResilienceTestLarge()
|
ErrorResilienceTestLarge()
|
||||||
: EncoderTest(GET_PARAM(0)), svc_support_(GET_PARAM(2)), psnr_(0.0),
|
: EncoderTest(GET_PARAM(0)),
|
||||||
nframes_(0), mismatch_psnr_(0.0), mismatch_nframes_(0),
|
svc_support_(GET_PARAM(2)),
|
||||||
|
psnr_(0.0),
|
||||||
|
nframes_(0),
|
||||||
|
mismatch_psnr_(0.0),
|
||||||
|
mismatch_nframes_(0),
|
||||||
encoding_mode_(GET_PARAM(1)) {
|
encoding_mode_(GET_PARAM(1)) {
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
@@ -63,26 +66,32 @@ class ErrorResilienceTestLarge
|
|||||||
// LAST is updated on base/layer 0, GOLDEN updated on layer 1.
|
// LAST is updated on base/layer 0, GOLDEN updated on layer 1.
|
||||||
// Non-zero pattern_switch parameter means pattern will switch to
|
// Non-zero pattern_switch parameter means pattern will switch to
|
||||||
// not using LAST for frame_num >= pattern_switch.
|
// not using LAST for frame_num >= pattern_switch.
|
||||||
int SetFrameFlags(int frame_num, int num_temp_layers, int pattern_switch) {
|
int SetFrameFlags(int frame_num,
|
||||||
|
int num_temp_layers,
|
||||||
|
int pattern_switch) {
|
||||||
int frame_flags = 0;
|
int frame_flags = 0;
|
||||||
if (num_temp_layers == 2) {
|
if (num_temp_layers == 2) {
|
||||||
if (frame_num % 2 == 0) {
|
if (frame_num % 2 == 0) {
|
||||||
if (frame_num < pattern_switch || pattern_switch == 0) {
|
if (frame_num < pattern_switch || pattern_switch == 0) {
|
||||||
// Layer 0: predict from LAST and ARF, update LAST.
|
// Layer 0: predict from LAST and ARF, update LAST.
|
||||||
frame_flags =
|
frame_flags = VP8_EFLAG_NO_REF_GF |
|
||||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_GF |
|
||||||
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
} else {
|
} else {
|
||||||
// Layer 0: predict from GF and ARF, update GF.
|
// Layer 0: predict from GF and ARF, update GF.
|
||||||
frame_flags = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_LAST |
|
frame_flags = VP8_EFLAG_NO_REF_LAST |
|
||||||
|
VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (frame_num < pattern_switch || pattern_switch == 0) {
|
if (frame_num < pattern_switch || pattern_switch == 0) {
|
||||||
// Layer 1: predict from L, GF, and ARF, update GF.
|
// Layer 1: predict from L, GF, and ARF, update GF.
|
||||||
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
frame_flags = VP8_EFLAG_NO_UPD_ARF |
|
||||||
|
VP8_EFLAG_NO_UPD_LAST;
|
||||||
} else {
|
} else {
|
||||||
// Layer 1: predict from GF and ARF, update GF.
|
// Layer 1: predict from GF and ARF, update GF.
|
||||||
frame_flags = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_LAST |
|
frame_flags = VP8_EFLAG_NO_REF_LAST |
|
||||||
|
VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,17 +99,20 @@ class ErrorResilienceTestLarge
|
|||||||
return frame_flags;
|
return frame_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video) {
|
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
||||||
frame_flags_ &=
|
::libvpx_test::Encoder * /*encoder*/) {
|
||||||
~(VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF);
|
frame_flags_ &= ~(VP8_EFLAG_NO_UPD_LAST |
|
||||||
|
VP8_EFLAG_NO_UPD_GF |
|
||||||
|
VP8_EFLAG_NO_UPD_ARF);
|
||||||
// For temporal layer case.
|
// For temporal layer case.
|
||||||
if (cfg_.ts_number_layers > 1) {
|
if (cfg_.ts_number_layers > 1) {
|
||||||
frame_flags_ =
|
frame_flags_ = SetFrameFlags(video->frame(),
|
||||||
SetFrameFlags(video->frame(), cfg_.ts_number_layers, pattern_switch_);
|
cfg_.ts_number_layers,
|
||||||
|
pattern_switch_);
|
||||||
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
|
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
|
||||||
if (droppable_frames_[i] == video->frame()) {
|
if (droppable_frames_[i] == video->frame()) {
|
||||||
std::cout << "Encoding droppable frame: " << droppable_frames_[i]
|
std::cout << "Encoding droppable frame: "
|
||||||
<< "\n";
|
<< droppable_frames_[i] << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -108,9 +120,10 @@ class ErrorResilienceTestLarge
|
|||||||
(cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
|
(cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
|
||||||
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
|
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
|
||||||
if (droppable_frames_[i] == video->frame()) {
|
if (droppable_frames_[i] == video->frame()) {
|
||||||
std::cout << "Encoding droppable frame: " << droppable_frames_[i]
|
std::cout << "Encoding droppable frame: "
|
||||||
<< "\n";
|
<< droppable_frames_[i] << "\n";
|
||||||
frame_flags_ |= (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
|
frame_flags_ |= (VP8_EFLAG_NO_UPD_LAST |
|
||||||
|
VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_UPD_ARF);
|
VP8_EFLAG_NO_UPD_ARF);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -120,12 +133,14 @@ class ErrorResilienceTestLarge
|
|||||||
}
|
}
|
||||||
|
|
||||||
double GetAveragePsnr() const {
|
double GetAveragePsnr() const {
|
||||||
if (nframes_) return psnr_ / nframes_;
|
if (nframes_)
|
||||||
|
return psnr_ / nframes_;
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double GetAverageMismatchPsnr() const {
|
double GetAverageMismatchPsnr() const {
|
||||||
if (mismatch_nframes_) return mismatch_psnr_ / mismatch_nframes_;
|
if (mismatch_nframes_)
|
||||||
|
return mismatch_psnr_ / mismatch_nframes_;
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,40 +158,42 @@ class ErrorResilienceTestLarge
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) {
|
virtual void MismatchHook(const vpx_image_t *img1,
|
||||||
|
const vpx_image_t *img2) {
|
||||||
double mismatch_psnr = compute_psnr(img1, img2);
|
double mismatch_psnr = compute_psnr(img1, img2);
|
||||||
mismatch_psnr_ += mismatch_psnr;
|
mismatch_psnr_ += mismatch_psnr;
|
||||||
++mismatch_nframes_;
|
++mismatch_nframes_;
|
||||||
// std::cout << "Mismatch frame psnr: " << mismatch_psnr << "\n";
|
// std::cout << "Mismatch frame psnr: " << mismatch_psnr << "\n";
|
||||||
|
::libvpx_test::EncoderTest::MismatchHook(img1, img2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetErrorFrames(int num, unsigned int *list) {
|
void SetErrorFrames(int num, unsigned int *list) {
|
||||||
if (num > kMaxErrorFrames) {
|
if (num > kMaxErrorFrames)
|
||||||
num = kMaxErrorFrames;
|
num = kMaxErrorFrames;
|
||||||
} else if (num < 0) {
|
else if (num < 0)
|
||||||
num = 0;
|
num = 0;
|
||||||
}
|
|
||||||
error_nframes_ = num;
|
error_nframes_ = num;
|
||||||
for (unsigned int i = 0; i < error_nframes_; ++i) {
|
for (unsigned int i = 0; i < error_nframes_; ++i)
|
||||||
error_frames_[i] = list[i];
|
error_frames_[i] = list[i];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void SetDroppableFrames(int num, unsigned int *list) {
|
void SetDroppableFrames(int num, unsigned int *list) {
|
||||||
if (num > kMaxDroppableFrames) {
|
if (num > kMaxDroppableFrames)
|
||||||
num = kMaxDroppableFrames;
|
num = kMaxDroppableFrames;
|
||||||
} else if (num < 0) {
|
else if (num < 0)
|
||||||
num = 0;
|
num = 0;
|
||||||
}
|
|
||||||
droppable_nframes_ = num;
|
droppable_nframes_ = num;
|
||||||
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
|
for (unsigned int i = 0; i < droppable_nframes_; ++i)
|
||||||
droppable_frames_[i] = list[i];
|
droppable_frames_[i] = list[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int GetMismatchFrames() {
|
||||||
|
return mismatch_nframes_;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int GetMismatchFrames() { return mismatch_nframes_; }
|
void SetPatternSwitch(int frame_switch) {
|
||||||
|
pattern_switch_ = frame_switch;
|
||||||
void SetPatternSwitch(int frame_switch) { pattern_switch_ = frame_switch; }
|
}
|
||||||
|
|
||||||
bool svc_support_;
|
bool svc_support_;
|
||||||
|
|
||||||
@@ -249,13 +266,14 @@ TEST_P(ErrorResilienceTestLarge, DropFramesWithoutRecovery) {
|
|||||||
// In addition to isolated loss/drop, add a long consecutive series
|
// In addition to isolated loss/drop, add a long consecutive series
|
||||||
// (of size 9) of dropped frames.
|
// (of size 9) of dropped frames.
|
||||||
unsigned int num_droppable_frames = 11;
|
unsigned int num_droppable_frames = 11;
|
||||||
unsigned int droppable_frame_list[] = { 5, 16, 22, 23, 24, 25,
|
unsigned int droppable_frame_list[] = {5, 16, 22, 23, 24, 25, 26, 27, 28,
|
||||||
26, 27, 28, 29, 30 };
|
29, 30};
|
||||||
SetDroppableFrames(num_droppable_frames, droppable_frame_list);
|
SetDroppableFrames(num_droppable_frames, droppable_frame_list);
|
||||||
SetErrorFrames(num_droppable_frames, droppable_frame_list);
|
SetErrorFrames(num_droppable_frames, droppable_frame_list);
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
// Test that no mismatches have been found
|
// Test that no mismatches have been found
|
||||||
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
|
std::cout << " Mismatch frames: "
|
||||||
|
<< GetMismatchFrames() << "\n";
|
||||||
EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
|
EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
|
||||||
|
|
||||||
// Reset previously set of error/droppable frames.
|
// Reset previously set of error/droppable frames.
|
||||||
@@ -289,7 +307,8 @@ TEST_P(ErrorResilienceTestLarge, DropFramesWithoutRecovery) {
|
|||||||
// layer, so successful decoding is expected.
|
// layer, so successful decoding is expected.
|
||||||
TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
|
TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
|
||||||
// This test doesn't run if SVC is not supported.
|
// This test doesn't run if SVC is not supported.
|
||||||
if (!svc_support_) return;
|
if (!svc_support_)
|
||||||
|
return;
|
||||||
|
|
||||||
const vpx_rational timebase = { 33333333, 1000000000 };
|
const vpx_rational timebase = { 33333333, 1000000000 };
|
||||||
cfg_.g_timebase = timebase;
|
cfg_.g_timebase = timebase;
|
||||||
@@ -324,7 +343,8 @@ TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
|
|||||||
SetErrorFrames(num_droppable_frames, droppable_frame_list);
|
SetErrorFrames(num_droppable_frames, droppable_frame_list);
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
// Test that no mismatches have been found
|
// Test that no mismatches have been found
|
||||||
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
|
std::cout << " Mismatch frames: "
|
||||||
|
<< GetMismatchFrames() << "\n";
|
||||||
EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
|
EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
|
||||||
|
|
||||||
// Reset previously set of error/droppable frames.
|
// Reset previously set of error/droppable frames.
|
||||||
@@ -336,7 +356,8 @@ TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
|
|||||||
// sequence, the LAST ref is not used anymore.
|
// sequence, the LAST ref is not used anymore.
|
||||||
TEST_P(ErrorResilienceTestLarge, 2LayersNoRefLast) {
|
TEST_P(ErrorResilienceTestLarge, 2LayersNoRefLast) {
|
||||||
// This test doesn't run if SVC is not supported.
|
// This test doesn't run if SVC is not supported.
|
||||||
if (!svc_support_) return;
|
if (!svc_support_)
|
||||||
|
return;
|
||||||
|
|
||||||
const vpx_rational timebase = { 33333333, 1000000000 };
|
const vpx_rational timebase = { 33333333, 1000000000 };
|
||||||
cfg_.g_timebase = timebase;
|
cfg_.g_timebase = timebase;
|
||||||
@@ -365,19 +386,20 @@ TEST_P(ErrorResilienceTestLarge, 2LayersNoRefLast) {
|
|||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
// Test that no mismatches have been found
|
// Test that no mismatches have been found
|
||||||
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
|
std::cout << " Mismatch frames: "
|
||||||
|
<< GetMismatchFrames() << "\n";
|
||||||
EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
|
EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
|
||||||
|
|
||||||
// Reset previously set of error/droppable frames.
|
// Reset previously set of error/droppable frames.
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
class ErrorResilienceTestLargeCodecControls
|
class ErrorResilienceTestLargeCodecControls : public ::libvpx_test::EncoderTest,
|
||||||
: public ::libvpx_test::EncoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||||
protected:
|
protected:
|
||||||
ErrorResilienceTestLargeCodecControls()
|
ErrorResilienceTestLargeCodecControls()
|
||||||
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)) {
|
: EncoderTest(GET_PARAM(0)),
|
||||||
|
encoding_mode_(GET_PARAM(1)) {
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,8 +438,8 @@ class ErrorResilienceTestLargeCodecControls
|
|||||||
if (num_temp_layers == 2) {
|
if (num_temp_layers == 2) {
|
||||||
if (frame_num % 2 == 0) {
|
if (frame_num % 2 == 0) {
|
||||||
// Layer 0: predict from L and ARF, update L.
|
// Layer 0: predict from L and ARF, update L.
|
||||||
frame_flags =
|
frame_flags = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
} else {
|
} else {
|
||||||
// Layer 1: predict from L, G and ARF, and update G.
|
// Layer 1: predict from L, G and ARF, and update G.
|
||||||
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
@@ -430,8 +452,8 @@ class ErrorResilienceTestLargeCodecControls
|
|||||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
|
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
|
||||||
} else if ((frame_num - 2) % 4 == 0) {
|
} else if ((frame_num - 2) % 4 == 0) {
|
||||||
// Layer 1: predict from L, G, update G.
|
// Layer 1: predict from L, G, update G.
|
||||||
frame_flags =
|
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_REF_ARF;
|
VP8_EFLAG_NO_REF_ARF;
|
||||||
} else if ((frame_num - 1) % 2 == 0) {
|
} else if ((frame_num - 1) % 2 == 0) {
|
||||||
// Layer 2: predict from L, G, ARF; update ARG.
|
// Layer 2: predict from L, G, ARF; update ARG.
|
||||||
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
|
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
|
||||||
@@ -503,15 +525,13 @@ class ErrorResilienceTestLargeCodecControls
|
|||||||
++layer) {
|
++layer) {
|
||||||
if (bits_total_[layer]) {
|
if (bits_total_[layer]) {
|
||||||
// Effective file datarate:
|
// Effective file datarate:
|
||||||
effective_datarate_[layer] =
|
effective_datarate_[layer] = (bits_total_[layer] / 1000.0) / duration_;
|
||||||
(bits_total_[layer] / 1000.0) / duration_;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double effective_datarate_[3];
|
double effective_datarate_[3];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
libvpx_test::TestMode encoding_mode_;
|
libvpx_test::TestMode encoding_mode_;
|
||||||
vpx_codec_pts_t last_pts_;
|
vpx_codec_pts_t last_pts_;
|
||||||
@@ -563,20 +583,15 @@ TEST_P(ErrorResilienceTestLargeCodecControls, CodecControl3TemporalLayers) {
|
|||||||
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
||||||
ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.75)
|
ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.75)
|
||||||
<< " The datarate for the file is lower than target by too much, "
|
<< " The datarate for the file is lower than target by too much, "
|
||||||
"for layer: "
|
"for layer: " << j;
|
||||||
<< j;
|
|
||||||
ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.25)
|
ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.25)
|
||||||
<< " The datarate for the file is greater than target by too much, "
|
<< " The datarate for the file is greater than target by too much, "
|
||||||
"for layer: "
|
"for layer: " << j;
|
||||||
<< j;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES,
|
// SVC-related tests don't run for VP10 since SVC is not supported.
|
||||||
::testing::Values(true));
|
VP10_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES,
|
||||||
VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLargeCodecControls,
|
::testing::Values(false));
|
||||||
ONE_PASS_TEST_MODES);
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES,
|
|
||||||
::testing::Values(true));
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
192
test/ethread_test.cc
Normal file
192
test/ethread_test.cc
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
#include "test/codec_factory.h"
|
||||||
|
#include "test/encode_test_driver.h"
|
||||||
|
#include "test/md5_helper.h"
|
||||||
|
#include "test/util.h"
|
||||||
|
#include "test/y4m_video_source.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class VPxEncoderThreadTest
|
||||||
|
: public ::libvpx_test::EncoderTest,
|
||||||
|
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||||
|
protected:
|
||||||
|
VPxEncoderThreadTest()
|
||||||
|
: EncoderTest(GET_PARAM(0)),
|
||||||
|
encoder_initialized_(false),
|
||||||
|
encoding_mode_(GET_PARAM(1)),
|
||||||
|
set_cpu_used_(GET_PARAM(2)) {
|
||||||
|
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||||
|
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||||
|
cfg.w = 1280;
|
||||||
|
cfg.h = 720;
|
||||||
|
decoder_ = codec_->CreateDecoder(cfg, 0);
|
||||||
|
#if CONFIG_VP10 && CONFIG_EXT_TILE
|
||||||
|
if (decoder_->IsVP10()) {
|
||||||
|
decoder_->Control(VP10_SET_DECODE_TILE_ROW, -1);
|
||||||
|
decoder_->Control(VP10_SET_DECODE_TILE_COL, -1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
size_enc_.clear();
|
||||||
|
md5_dec_.clear();
|
||||||
|
md5_enc_.clear();
|
||||||
|
}
|
||||||
|
virtual ~VPxEncoderThreadTest() {
|
||||||
|
delete decoder_;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void SetUp() {
|
||||||
|
InitializeConfig();
|
||||||
|
SetMode(encoding_mode_);
|
||||||
|
|
||||||
|
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
||||||
|
cfg_.g_lag_in_frames = 3;
|
||||||
|
cfg_.rc_end_usage = VPX_VBR;
|
||||||
|
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||||
|
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
||||||
|
} else {
|
||||||
|
cfg_.g_lag_in_frames = 0;
|
||||||
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
|
cfg_.g_error_resilient = 1;
|
||||||
|
}
|
||||||
|
cfg_.rc_max_quantizer = 56;
|
||||||
|
cfg_.rc_min_quantizer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||||
|
encoder_initialized_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource * /*video*/,
|
||||||
|
::libvpx_test::Encoder *encoder) {
|
||||||
|
if (!encoder_initialized_) {
|
||||||
|
#if CONFIG_VP10 && CONFIG_EXT_TILE
|
||||||
|
encoder->Control(VP9E_SET_TILE_COLUMNS, 1);
|
||||||
|
if (codec_ == &libvpx_test::kVP10) {
|
||||||
|
// TODO(geza): Start using multiple tile rows when the multi-threaded
|
||||||
|
// encoder can handle them
|
||||||
|
encoder->Control(VP9E_SET_TILE_ROWS, 32);
|
||||||
|
} else {
|
||||||
|
encoder->Control(VP9E_SET_TILE_ROWS, 0);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Encode 4 tile columns.
|
||||||
|
encoder->Control(VP9E_SET_TILE_COLUMNS, 2);
|
||||||
|
encoder->Control(VP9E_SET_TILE_ROWS, 0);
|
||||||
|
#endif // CONFIG_VP10 && CONFIG_EXT_TILE
|
||||||
|
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||||
|
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
||||||
|
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||||
|
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
||||||
|
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
|
||||||
|
encoder->Control(VP8E_SET_ARNR_TYPE, 3);
|
||||||
|
} else {
|
||||||
|
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 0);
|
||||||
|
encoder->Control(VP9E_SET_AQ_MODE, 3);
|
||||||
|
}
|
||||||
|
encoder_initialized_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||||
|
size_enc_.push_back(pkt->data.frame.sz);
|
||||||
|
|
||||||
|
::libvpx_test::MD5 md5_enc;
|
||||||
|
md5_enc.Add(reinterpret_cast<uint8_t*>(pkt->data.frame.buf),
|
||||||
|
pkt->data.frame.sz);
|
||||||
|
md5_enc_.push_back(md5_enc.Get());
|
||||||
|
|
||||||
|
const vpx_codec_err_t res = decoder_->DecodeFrame(
|
||||||
|
reinterpret_cast<uint8_t*>(pkt->data.frame.buf), pkt->data.frame.sz);
|
||||||
|
if (res != VPX_CODEC_OK) {
|
||||||
|
abort_ = true;
|
||||||
|
ASSERT_EQ(VPX_CODEC_OK, res);
|
||||||
|
}
|
||||||
|
const vpx_image_t *img = decoder_->GetDxData().Next();
|
||||||
|
|
||||||
|
if (img) {
|
||||||
|
::libvpx_test::MD5 md5_res;
|
||||||
|
md5_res.Add(img);
|
||||||
|
md5_dec_.push_back(md5_res.Get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoTest() {
|
||||||
|
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 15, 18);
|
||||||
|
cfg_.rc_target_bitrate = 1000;
|
||||||
|
|
||||||
|
// Encode using single thread.
|
||||||
|
cfg_.g_threads = 1;
|
||||||
|
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
std::vector<size_t> single_thr_size_enc;
|
||||||
|
std::vector<std::string> single_thr_md5_enc;
|
||||||
|
std::vector<std::string> single_thr_md5_dec;
|
||||||
|
single_thr_size_enc = size_enc_;
|
||||||
|
single_thr_md5_enc = md5_enc_;
|
||||||
|
single_thr_md5_dec = md5_dec_;
|
||||||
|
size_enc_.clear();
|
||||||
|
md5_enc_.clear();
|
||||||
|
md5_dec_.clear();
|
||||||
|
|
||||||
|
// Encode using multiple threads.
|
||||||
|
cfg_.g_threads = 4;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
std::vector<size_t> multi_thr_size_enc;
|
||||||
|
std::vector<std::string> multi_thr_md5_enc;
|
||||||
|
std::vector<std::string> multi_thr_md5_dec;
|
||||||
|
multi_thr_size_enc = size_enc_;
|
||||||
|
multi_thr_md5_enc = md5_enc_;
|
||||||
|
multi_thr_md5_dec = md5_dec_;
|
||||||
|
size_enc_.clear();
|
||||||
|
md5_enc_.clear();
|
||||||
|
md5_dec_.clear();
|
||||||
|
|
||||||
|
// Check that the vectors are equal.
|
||||||
|
ASSERT_EQ(single_thr_size_enc, multi_thr_size_enc);
|
||||||
|
ASSERT_EQ(single_thr_md5_enc, multi_thr_md5_enc);
|
||||||
|
ASSERT_EQ(single_thr_md5_dec, multi_thr_md5_dec);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool encoder_initialized_;
|
||||||
|
::libvpx_test::TestMode encoding_mode_;
|
||||||
|
int set_cpu_used_;
|
||||||
|
::libvpx_test::Decoder *decoder_;
|
||||||
|
std::vector<size_t> size_enc_;
|
||||||
|
std::vector<std::string> md5_enc_;
|
||||||
|
std::vector<std::string> md5_dec_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(VPxEncoderThreadTest, EncoderResultTest) {
|
||||||
|
DoTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
class VPxEncoderThreadTestLarge : public VPxEncoderThreadTest {};
|
||||||
|
|
||||||
|
TEST_P(VPxEncoderThreadTestLarge, EncoderResultTest) {
|
||||||
|
DoTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VP10_INSTANTIATE_TEST_CASE(
|
||||||
|
VPxEncoderThreadTest,
|
||||||
|
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood),
|
||||||
|
::testing::Range(3, 9));
|
||||||
|
|
||||||
|
VP10_INSTANTIATE_TEST_CASE(
|
||||||
|
VPxEncoderThreadTestLarge,
|
||||||
|
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood),
|
||||||
|
::testing::Range(1, 3));
|
||||||
|
} // namespace
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
example_tests=$(ls $(dirname $0)/*.sh)
|
example_tests=$(ls $(dirname $0)/*.sh)
|
||||||
|
|
||||||
# List of script names to exclude.
|
# List of script names to exclude.
|
||||||
exclude_list="examples stress tools_common"
|
exclude_list="examples tools_common"
|
||||||
|
|
||||||
# Filter out the scripts in $exclude_list.
|
# Filter out the scripts in $exclude_list.
|
||||||
for word in ${exclude_list}; do
|
for word in ${exclude_list}; do
|
||||||
|
|||||||
@@ -1,517 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "test/codec_factory.h"
|
|
||||||
#include "test/decode_test_driver.h"
|
|
||||||
#include "test/ivf_video_source.h"
|
|
||||||
#include "test/md5_helper.h"
|
|
||||||
#include "test/test_vectors.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
#if CONFIG_WEBM_IO
|
|
||||||
#include "test/webm_video_source.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
const int kVideoNameParam = 1;
|
|
||||||
|
|
||||||
struct ExternalFrameBuffer {
|
|
||||||
uint8_t *data;
|
|
||||||
size_t size;
|
|
||||||
int in_use;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Class to manipulate a list of external frame buffers.
|
|
||||||
class ExternalFrameBufferList {
|
|
||||||
public:
|
|
||||||
ExternalFrameBufferList()
|
|
||||||
: num_buffers_(0), num_used_buffers_(0), ext_fb_list_(NULL) {}
|
|
||||||
|
|
||||||
virtual ~ExternalFrameBufferList() {
|
|
||||||
for (int i = 0; i < num_buffers_; ++i) {
|
|
||||||
delete[] ext_fb_list_[i].data;
|
|
||||||
}
|
|
||||||
delete[] ext_fb_list_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates the list to hold the external buffers. Returns true on success.
|
|
||||||
bool CreateBufferList(int num_buffers) {
|
|
||||||
if (num_buffers < 0) return false;
|
|
||||||
|
|
||||||
num_buffers_ = num_buffers;
|
|
||||||
ext_fb_list_ = new ExternalFrameBuffer[num_buffers_];
|
|
||||||
EXPECT_TRUE(ext_fb_list_ != NULL);
|
|
||||||
memset(ext_fb_list_, 0, sizeof(ext_fb_list_[0]) * num_buffers_);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Searches the frame buffer list for a free frame buffer. Makes sure
|
|
||||||
// that the frame buffer is at least |min_size| in bytes. Marks that the
|
|
||||||
// frame buffer is in use by libvpx. Finally sets |fb| to point to the
|
|
||||||
// external frame buffer. Returns < 0 on an error.
|
|
||||||
int GetFreeFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) {
|
|
||||||
EXPECT_TRUE(fb != NULL);
|
|
||||||
const int idx = FindFreeBufferIndex();
|
|
||||||
if (idx == num_buffers_) return -1;
|
|
||||||
|
|
||||||
if (ext_fb_list_[idx].size < min_size) {
|
|
||||||
delete[] ext_fb_list_[idx].data;
|
|
||||||
ext_fb_list_[idx].data = new uint8_t[min_size];
|
|
||||||
memset(ext_fb_list_[idx].data, 0, min_size);
|
|
||||||
ext_fb_list_[idx].size = min_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetFrameBuffer(idx, fb);
|
|
||||||
|
|
||||||
num_used_buffers_++;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test function that will not allocate any data for the frame buffer.
|
|
||||||
// Returns < 0 on an error.
|
|
||||||
int GetZeroFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) {
|
|
||||||
EXPECT_TRUE(fb != NULL);
|
|
||||||
const int idx = FindFreeBufferIndex();
|
|
||||||
if (idx == num_buffers_) return -1;
|
|
||||||
|
|
||||||
if (ext_fb_list_[idx].size < min_size) {
|
|
||||||
delete[] ext_fb_list_[idx].data;
|
|
||||||
ext_fb_list_[idx].data = NULL;
|
|
||||||
ext_fb_list_[idx].size = min_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetFrameBuffer(idx, fb);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marks the external frame buffer that |fb| is pointing to as free.
|
|
||||||
// Returns < 0 on an error.
|
|
||||||
int ReturnFrameBuffer(vpx_codec_frame_buffer_t *fb) {
|
|
||||||
if (fb == NULL) {
|
|
||||||
EXPECT_TRUE(fb != NULL);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ExternalFrameBuffer *const ext_fb =
|
|
||||||
reinterpret_cast<ExternalFrameBuffer *>(fb->priv);
|
|
||||||
if (ext_fb == NULL) {
|
|
||||||
EXPECT_TRUE(ext_fb != NULL);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
EXPECT_EQ(1, ext_fb->in_use);
|
|
||||||
ext_fb->in_use = 0;
|
|
||||||
num_used_buffers_--;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks that the ximage data is contained within the external frame buffer
|
|
||||||
// private data passed back in the ximage.
|
|
||||||
void CheckXImageFrameBuffer(const vpx_image_t *img) {
|
|
||||||
if (img->fb_priv != NULL) {
|
|
||||||
const struct ExternalFrameBuffer *const ext_fb =
|
|
||||||
reinterpret_cast<ExternalFrameBuffer *>(img->fb_priv);
|
|
||||||
|
|
||||||
ASSERT_TRUE(img->planes[0] >= ext_fb->data &&
|
|
||||||
img->planes[0] < (ext_fb->data + ext_fb->size));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int num_used_buffers() const { return num_used_buffers_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Returns the index of the first free frame buffer. Returns |num_buffers_|
|
|
||||||
// if there are no free frame buffers.
|
|
||||||
int FindFreeBufferIndex() {
|
|
||||||
int i;
|
|
||||||
// Find a free frame buffer.
|
|
||||||
for (i = 0; i < num_buffers_; ++i) {
|
|
||||||
if (!ext_fb_list_[i].in_use) break;
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets |fb| to an external frame buffer. idx is the index into the frame
|
|
||||||
// buffer list.
|
|
||||||
void SetFrameBuffer(int idx, vpx_codec_frame_buffer_t *fb) {
|
|
||||||
ASSERT_TRUE(fb != NULL);
|
|
||||||
fb->data = ext_fb_list_[idx].data;
|
|
||||||
fb->size = ext_fb_list_[idx].size;
|
|
||||||
ASSERT_EQ(0, ext_fb_list_[idx].in_use);
|
|
||||||
ext_fb_list_[idx].in_use = 1;
|
|
||||||
fb->priv = &ext_fb_list_[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
int num_buffers_;
|
|
||||||
int num_used_buffers_;
|
|
||||||
ExternalFrameBuffer *ext_fb_list_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if CONFIG_WEBM_IO
|
|
||||||
|
|
||||||
// Callback used by libvpx to request the application to return a frame
|
|
||||||
// buffer of at least |min_size| in bytes.
|
|
||||||
int get_vp9_frame_buffer(void *user_priv, size_t min_size,
|
|
||||||
vpx_codec_frame_buffer_t *fb) {
|
|
||||||
ExternalFrameBufferList *const fb_list =
|
|
||||||
reinterpret_cast<ExternalFrameBufferList *>(user_priv);
|
|
||||||
return fb_list->GetFreeFrameBuffer(min_size, fb);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback used by libvpx to tell the application that |fb| is not needed
|
|
||||||
// anymore.
|
|
||||||
int release_vp9_frame_buffer(void *user_priv, vpx_codec_frame_buffer_t *fb) {
|
|
||||||
ExternalFrameBufferList *const fb_list =
|
|
||||||
reinterpret_cast<ExternalFrameBufferList *>(user_priv);
|
|
||||||
return fb_list->ReturnFrameBuffer(fb);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback will not allocate data for frame buffer.
|
|
||||||
int get_vp9_zero_frame_buffer(void *user_priv, size_t min_size,
|
|
||||||
vpx_codec_frame_buffer_t *fb) {
|
|
||||||
ExternalFrameBufferList *const fb_list =
|
|
||||||
reinterpret_cast<ExternalFrameBufferList *>(user_priv);
|
|
||||||
return fb_list->GetZeroFrameBuffer(min_size, fb);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback will allocate one less byte than |min_size|.
|
|
||||||
int get_vp9_one_less_byte_frame_buffer(void *user_priv, size_t min_size,
|
|
||||||
vpx_codec_frame_buffer_t *fb) {
|
|
||||||
ExternalFrameBufferList *const fb_list =
|
|
||||||
reinterpret_cast<ExternalFrameBufferList *>(user_priv);
|
|
||||||
return fb_list->GetFreeFrameBuffer(min_size - 1, fb);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback will not release the external frame buffer.
|
|
||||||
int do_not_release_vp9_frame_buffer(void *user_priv,
|
|
||||||
vpx_codec_frame_buffer_t *fb) {
|
|
||||||
(void)user_priv;
|
|
||||||
(void)fb;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CONFIG_WEBM_IO
|
|
||||||
|
|
||||||
// Class for testing passing in external frame buffers to libvpx.
|
|
||||||
class ExternalFrameBufferMD5Test
|
|
||||||
: public ::libvpx_test::DecoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWithParam<const char *> {
|
|
||||||
protected:
|
|
||||||
ExternalFrameBufferMD5Test()
|
|
||||||
: DecoderTest(GET_PARAM(::libvpx_test::kCodecFactoryParam)),
|
|
||||||
md5_file_(NULL), num_buffers_(0) {}
|
|
||||||
|
|
||||||
virtual ~ExternalFrameBufferMD5Test() {
|
|
||||||
if (md5_file_ != NULL) fclose(md5_file_);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void PreDecodeFrameHook(
|
|
||||||
const libvpx_test::CompressedVideoSource &video,
|
|
||||||
libvpx_test::Decoder *decoder) {
|
|
||||||
if (num_buffers_ > 0 && video.frame_number() == 0) {
|
|
||||||
// Have libvpx use frame buffers we create.
|
|
||||||
ASSERT_TRUE(fb_list_.CreateBufferList(num_buffers_));
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK,
|
|
||||||
decoder->SetFrameBufferFunctions(GetVP9FrameBuffer,
|
|
||||||
ReleaseVP9FrameBuffer, this));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenMD5File(const std::string &md5_file_name_) {
|
|
||||||
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
|
|
||||||
ASSERT_TRUE(md5_file_ != NULL)
|
|
||||||
<< "Md5 file open failed. Filename: " << md5_file_name_;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
|
||||||
const unsigned int frame_number) {
|
|
||||||
ASSERT_TRUE(md5_file_ != NULL);
|
|
||||||
char expected_md5[33];
|
|
||||||
char junk[128];
|
|
||||||
|
|
||||||
// Read correct md5 checksums.
|
|
||||||
const int res = fscanf(md5_file_, "%s %s", expected_md5, junk);
|
|
||||||
ASSERT_NE(EOF, res) << "Read md5 data failed";
|
|
||||||
expected_md5[32] = '\0';
|
|
||||||
|
|
||||||
::libvpx_test::MD5 md5_res;
|
|
||||||
md5_res.Add(&img);
|
|
||||||
const char *const actual_md5 = md5_res.Get();
|
|
||||||
|
|
||||||
// Check md5 match.
|
|
||||||
ASSERT_STREQ(expected_md5, actual_md5)
|
|
||||||
<< "Md5 checksums don't match: frame number = " << frame_number;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback to get a free external frame buffer. Return value < 0 is an
|
|
||||||
// error.
|
|
||||||
static int GetVP9FrameBuffer(void *user_priv, size_t min_size,
|
|
||||||
vpx_codec_frame_buffer_t *fb) {
|
|
||||||
ExternalFrameBufferMD5Test *const md5Test =
|
|
||||||
reinterpret_cast<ExternalFrameBufferMD5Test *>(user_priv);
|
|
||||||
return md5Test->fb_list_.GetFreeFrameBuffer(min_size, fb);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback to release an external frame buffer. Return value < 0 is an
|
|
||||||
// error.
|
|
||||||
static int ReleaseVP9FrameBuffer(void *user_priv,
|
|
||||||
vpx_codec_frame_buffer_t *fb) {
|
|
||||||
ExternalFrameBufferMD5Test *const md5Test =
|
|
||||||
reinterpret_cast<ExternalFrameBufferMD5Test *>(user_priv);
|
|
||||||
return md5Test->fb_list_.ReturnFrameBuffer(fb);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_num_buffers(int num_buffers) { num_buffers_ = num_buffers; }
|
|
||||||
int num_buffers() const { return num_buffers_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
FILE *md5_file_;
|
|
||||||
int num_buffers_;
|
|
||||||
ExternalFrameBufferList fb_list_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if CONFIG_WEBM_IO
|
|
||||||
const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm";
|
|
||||||
const char kVP9NonRefTestFile[] = "vp90-2-22-svc_1280x720_1.webm";
|
|
||||||
|
|
||||||
// Class for testing passing in external frame buffers to libvpx.
|
|
||||||
class ExternalFrameBufferTest : public ::testing::Test {
|
|
||||||
protected:
|
|
||||||
ExternalFrameBufferTest() : video_(NULL), decoder_(NULL), num_buffers_(0) {}
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
|
||||||
video_ = new libvpx_test::WebMVideoSource(kVP9TestFile);
|
|
||||||
ASSERT_TRUE(video_ != NULL);
|
|
||||||
video_->Init();
|
|
||||||
video_->Begin();
|
|
||||||
|
|
||||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
|
||||||
decoder_ = new libvpx_test::VP9Decoder(cfg, 0);
|
|
||||||
ASSERT_TRUE(decoder_ != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void TearDown() {
|
|
||||||
delete decoder_;
|
|
||||||
decoder_ = NULL;
|
|
||||||
delete video_;
|
|
||||||
video_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Passes the external frame buffer information to libvpx.
|
|
||||||
vpx_codec_err_t SetFrameBufferFunctions(
|
|
||||||
int num_buffers, vpx_get_frame_buffer_cb_fn_t cb_get,
|
|
||||||
vpx_release_frame_buffer_cb_fn_t cb_release) {
|
|
||||||
if (num_buffers > 0) {
|
|
||||||
num_buffers_ = num_buffers;
|
|
||||||
EXPECT_TRUE(fb_list_.CreateBufferList(num_buffers_));
|
|
||||||
}
|
|
||||||
|
|
||||||
return decoder_->SetFrameBufferFunctions(cb_get, cb_release, &fb_list_);
|
|
||||||
}
|
|
||||||
|
|
||||||
vpx_codec_err_t DecodeOneFrame() {
|
|
||||||
const vpx_codec_err_t res =
|
|
||||||
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
|
|
||||||
CheckDecodedFrames();
|
|
||||||
if (res == VPX_CODEC_OK) video_->Next();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
vpx_codec_err_t DecodeRemainingFrames() {
|
|
||||||
for (; video_->cxdata() != NULL; video_->Next()) {
|
|
||||||
const vpx_codec_err_t res =
|
|
||||||
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
|
|
||||||
if (res != VPX_CODEC_OK) return res;
|
|
||||||
CheckDecodedFrames();
|
|
||||||
}
|
|
||||||
return VPX_CODEC_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void CheckDecodedFrames() {
|
|
||||||
libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData();
|
|
||||||
const vpx_image_t *img = NULL;
|
|
||||||
|
|
||||||
// Get decompressed data
|
|
||||||
while ((img = dec_iter.Next()) != NULL) {
|
|
||||||
fb_list_.CheckXImageFrameBuffer(img);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
libvpx_test::WebMVideoSource *video_;
|
|
||||||
libvpx_test::VP9Decoder *decoder_;
|
|
||||||
int num_buffers_;
|
|
||||||
ExternalFrameBufferList fb_list_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ExternalFrameBufferNonRefTest : public ExternalFrameBufferTest {
|
|
||||||
protected:
|
|
||||||
virtual void SetUp() {
|
|
||||||
video_ = new libvpx_test::WebMVideoSource(kVP9NonRefTestFile);
|
|
||||||
ASSERT_TRUE(video_ != NULL);
|
|
||||||
video_->Init();
|
|
||||||
video_->Begin();
|
|
||||||
|
|
||||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
|
||||||
decoder_ = new libvpx_test::VP9Decoder(cfg, 0);
|
|
||||||
ASSERT_TRUE(decoder_ != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void CheckFrameBufferRelease() {
|
|
||||||
TearDown();
|
|
||||||
ASSERT_EQ(0, fb_list_.num_used_buffers());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif // CONFIG_WEBM_IO
|
|
||||||
|
|
||||||
// This test runs through the set of test vectors, and decodes them.
|
|
||||||
// Libvpx will call into the application to allocate a frame buffer when
|
|
||||||
// needed. The md5 checksums are computed for each frame in the video file.
|
|
||||||
// If md5 checksums match the correct md5 data, then the test is passed.
|
|
||||||
// Otherwise, the test failed.
|
|
||||||
TEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) {
|
|
||||||
const std::string filename = GET_PARAM(kVideoNameParam);
|
|
||||||
|
|
||||||
// Number of buffers equals #VP9_MAXIMUM_REF_BUFFERS +
|
|
||||||
// #VPX_MAXIMUM_WORK_BUFFERS + four jitter buffers.
|
|
||||||
const int jitter_buffers = 4;
|
|
||||||
const int num_buffers =
|
|
||||||
VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS + jitter_buffers;
|
|
||||||
set_num_buffers(num_buffers);
|
|
||||||
|
|
||||||
#if CONFIG_VP8_DECODER
|
|
||||||
// Tell compiler we are not using kVP8TestVectors.
|
|
||||||
(void)libvpx_test::kVP8TestVectors;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Open compressed video file.
|
|
||||||
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
|
||||||
if (filename.substr(filename.length() - 3, 3) == "ivf") {
|
|
||||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
|
||||||
} else {
|
|
||||||
#if CONFIG_WEBM_IO
|
|
||||||
video.reset(new libvpx_test::WebMVideoSource(filename));
|
|
||||||
#else
|
|
||||||
fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
|
|
||||||
filename.c_str());
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
ASSERT_TRUE(video.get() != NULL);
|
|
||||||
video->Init();
|
|
||||||
|
|
||||||
// Construct md5 file name.
|
|
||||||
const std::string md5_filename = filename + ".md5";
|
|
||||||
OpenMD5File(md5_filename);
|
|
||||||
|
|
||||||
// Decode frame, and check the md5 matching.
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CONFIG_WEBM_IO
|
|
||||||
TEST_F(ExternalFrameBufferTest, MinFrameBuffers) {
|
|
||||||
// Minimum number of external frame buffers for VP9 is
|
|
||||||
// #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS.
|
|
||||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK,
|
|
||||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
|
||||||
release_vp9_frame_buffer));
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ExternalFrameBufferTest, EightJitterBuffers) {
|
|
||||||
// Number of buffers equals #VP9_MAXIMUM_REF_BUFFERS +
|
|
||||||
// #VPX_MAXIMUM_WORK_BUFFERS + eight jitter buffers.
|
|
||||||
const int jitter_buffers = 8;
|
|
||||||
const int num_buffers =
|
|
||||||
VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS + jitter_buffers;
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK,
|
|
||||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
|
||||||
release_vp9_frame_buffer));
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ExternalFrameBufferTest, NotEnoughBuffers) {
|
|
||||||
// Minimum number of external frame buffers for VP9 is
|
|
||||||
// #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS. Most files will
|
|
||||||
// only use 5 frame buffers at one time.
|
|
||||||
const int num_buffers = 2;
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK,
|
|
||||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
|
||||||
release_vp9_frame_buffer));
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
|
|
||||||
// Only run this on long clips. Decoding a very short clip will return
|
|
||||||
// VPX_CODEC_OK even with only 2 buffers.
|
|
||||||
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeRemainingFrames());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ExternalFrameBufferTest, NoRelease) {
|
|
||||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK,
|
|
||||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
|
||||||
do_not_release_vp9_frame_buffer));
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
|
|
||||||
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeRemainingFrames());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ExternalFrameBufferTest, NullRealloc) {
|
|
||||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK,
|
|
||||||
SetFrameBufferFunctions(num_buffers, get_vp9_zero_frame_buffer,
|
|
||||||
release_vp9_frame_buffer));
|
|
||||||
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeOneFrame());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ExternalFrameBufferTest, ReallocOneLessByte) {
|
|
||||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK, SetFrameBufferFunctions(
|
|
||||||
num_buffers, get_vp9_one_less_byte_frame_buffer,
|
|
||||||
release_vp9_frame_buffer));
|
|
||||||
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeOneFrame());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ExternalFrameBufferTest, NullGetFunction) {
|
|
||||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
|
||||||
ASSERT_EQ(
|
|
||||||
VPX_CODEC_INVALID_PARAM,
|
|
||||||
SetFrameBufferFunctions(num_buffers, NULL, release_vp9_frame_buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ExternalFrameBufferTest, NullReleaseFunction) {
|
|
||||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
|
||||||
ASSERT_EQ(VPX_CODEC_INVALID_PARAM,
|
|
||||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer, NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ExternalFrameBufferTest, SetAfterDecode) {
|
|
||||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
|
|
||||||
ASSERT_EQ(VPX_CODEC_ERROR,
|
|
||||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
|
||||||
release_vp9_frame_buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ExternalFrameBufferNonRefTest, ReleaseNonRefFrameBuffer) {
|
|
||||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK,
|
|
||||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
|
||||||
release_vp9_frame_buffer));
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
|
|
||||||
CheckFrameBufferRelease();
|
|
||||||
}
|
|
||||||
#endif // CONFIG_WEBM_IO
|
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(
|
|
||||||
ExternalFrameBufferMD5Test,
|
|
||||||
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
|
||||||
libvpx_test::kVP9TestVectors +
|
|
||||||
libvpx_test::kNumVP9TestVectors));
|
|
||||||
} // namespace
|
|
||||||
385
test/fdct4x4_test.cc
Normal file
385
test/fdct4x4_test.cc
Normal file
@@ -0,0 +1,385 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "./vp10_rtcd.h"
|
||||||
|
#include "./vpx_dsp_rtcd.h"
|
||||||
|
#include "test/acm_random.h"
|
||||||
|
#include "test/clear_system_state.h"
|
||||||
|
#include "test/register_state_check.h"
|
||||||
|
#include "test/transform_test_base.h"
|
||||||
|
#include "test/util.h"
|
||||||
|
#include "vp10/common/entropy.h"
|
||||||
|
#include "vpx/vpx_codec.h"
|
||||||
|
#include "vpx/vpx_integer.h"
|
||||||
|
#include "vpx_ports/mem.h"
|
||||||
|
|
||||||
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride);
|
||||||
|
typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride);
|
||||||
|
typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride,
|
||||||
|
int tx_type);
|
||||||
|
using libvpx_test::FhtFunc;
|
||||||
|
|
||||||
|
typedef std::tr1::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t, int>
|
||||||
|
Dct4x4Param;
|
||||||
|
typedef std::tr1::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t, int>
|
||||||
|
Ht4x4Param;
|
||||||
|
|
||||||
|
void fdct4x4_ref(const int16_t *in, tran_low_t *out, int stride,
|
||||||
|
int /*tx_type*/) {
|
||||||
|
vpx_fdct4x4_c(in, out, stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fht4x4_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
||||||
|
vp10_fht4x4_c(in, out, stride, tx_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fwht4x4_ref(const int16_t *in, tran_low_t *out, int stride,
|
||||||
|
int /*tx_type*/) {
|
||||||
|
vp10_fwht4x4_c(in, out, stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
void idct4x4_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
|
vpx_highbd_idct4x4_16_add_c(in, out, stride, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void idct4x4_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
|
vpx_highbd_idct4x4_16_add_c(in, out, stride, 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iht4x4_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||||
|
vp10_highbd_iht4x4_16_add_c(in, out, stride, tx_type, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iht4x4_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||||
|
vp10_highbd_iht4x4_16_add_c(in, out, stride, tx_type, 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iwht4x4_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
|
vpx_highbd_iwht4x4_16_add_c(in, out, stride, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iwht4x4_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
|
vpx_highbd_iwht4x4_16_add_c(in, out, stride, 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_SSE2
|
||||||
|
void idct4x4_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
|
vpx_highbd_idct4x4_16_add_sse2(in, out, stride, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void idct4x4_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
|
vpx_highbd_idct4x4_16_add_sse2(in, out, stride, 12);
|
||||||
|
}
|
||||||
|
#endif // HAVE_SSE2
|
||||||
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
|
||||||
|
|
||||||
|
class Trans4x4DCT
|
||||||
|
: public libvpx_test::TransformTestBase,
|
||||||
|
public ::testing::TestWithParam<Dct4x4Param> {
|
||||||
|
public:
|
||||||
|
virtual ~Trans4x4DCT() {}
|
||||||
|
|
||||||
|
virtual void SetUp() {
|
||||||
|
fwd_txfm_ = GET_PARAM(0);
|
||||||
|
inv_txfm_ = GET_PARAM(1);
|
||||||
|
tx_type_ = GET_PARAM(2);
|
||||||
|
pitch_ = 4;
|
||||||
|
fwd_txfm_ref = fdct4x4_ref;
|
||||||
|
bit_depth_ = GET_PARAM(3);
|
||||||
|
mask_ = (1 << bit_depth_) - 1;
|
||||||
|
num_coeffs_ = GET_PARAM(4);
|
||||||
|
}
|
||||||
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void RunFwdTxfm(const int16_t *in, tran_low_t *out, int stride) {
|
||||||
|
fwd_txfm_(in, out, stride);
|
||||||
|
}
|
||||||
|
void RunInvTxfm(const tran_low_t *out, uint8_t *dst, int stride) {
|
||||||
|
inv_txfm_(out, dst, stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
FdctFunc fwd_txfm_;
|
||||||
|
IdctFunc inv_txfm_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(Trans4x4DCT, AccuracyCheck) {
|
||||||
|
RunAccuracyCheck(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(Trans4x4DCT, CoeffCheck) {
|
||||||
|
RunCoeffCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(Trans4x4DCT, MemCheck) {
|
||||||
|
RunMemCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(Trans4x4DCT, InvAccuracyCheck) {
|
||||||
|
RunInvAccuracyCheck(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Trans4x4HT
|
||||||
|
: public libvpx_test::TransformTestBase,
|
||||||
|
public ::testing::TestWithParam<Ht4x4Param> {
|
||||||
|
public:
|
||||||
|
virtual ~Trans4x4HT() {}
|
||||||
|
|
||||||
|
virtual void SetUp() {
|
||||||
|
fwd_txfm_ = GET_PARAM(0);
|
||||||
|
inv_txfm_ = GET_PARAM(1);
|
||||||
|
tx_type_ = GET_PARAM(2);
|
||||||
|
pitch_ = 4;
|
||||||
|
fwd_txfm_ref = fht4x4_ref;
|
||||||
|
bit_depth_ = GET_PARAM(3);
|
||||||
|
mask_ = (1 << bit_depth_) - 1;
|
||||||
|
num_coeffs_ = GET_PARAM(4);
|
||||||
|
}
|
||||||
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void RunFwdTxfm(const int16_t *in, tran_low_t *out, int stride) {
|
||||||
|
fwd_txfm_(in, out, stride, tx_type_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunInvTxfm(const tran_low_t *out, uint8_t *dst, int stride) {
|
||||||
|
inv_txfm_(out, dst, stride, tx_type_);
|
||||||
|
}
|
||||||
|
|
||||||
|
FhtFunc fwd_txfm_;
|
||||||
|
IhtFunc inv_txfm_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(Trans4x4HT, AccuracyCheck) {
|
||||||
|
RunAccuracyCheck(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(Trans4x4HT, CoeffCheck) {
|
||||||
|
RunCoeffCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(Trans4x4HT, MemCheck) {
|
||||||
|
RunMemCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(Trans4x4HT, InvAccuracyCheck) {
|
||||||
|
RunInvAccuracyCheck(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Trans4x4WHT
|
||||||
|
: public libvpx_test::TransformTestBase,
|
||||||
|
public ::testing::TestWithParam<Dct4x4Param> {
|
||||||
|
public:
|
||||||
|
virtual ~Trans4x4WHT() {}
|
||||||
|
|
||||||
|
virtual void SetUp() {
|
||||||
|
fwd_txfm_ = GET_PARAM(0);
|
||||||
|
inv_txfm_ = GET_PARAM(1);
|
||||||
|
tx_type_ = GET_PARAM(2);
|
||||||
|
pitch_ = 4;
|
||||||
|
fwd_txfm_ref = fwht4x4_ref;
|
||||||
|
bit_depth_ = GET_PARAM(3);
|
||||||
|
mask_ = (1 << bit_depth_) - 1;
|
||||||
|
num_coeffs_ = GET_PARAM(4);
|
||||||
|
}
|
||||||
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void RunFwdTxfm(const int16_t *in, tran_low_t *out, int stride) {
|
||||||
|
fwd_txfm_(in, out, stride);
|
||||||
|
}
|
||||||
|
void RunInvTxfm(const tran_low_t *out, uint8_t *dst, int stride) {
|
||||||
|
inv_txfm_(out, dst, stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
FdctFunc fwd_txfm_;
|
||||||
|
IdctFunc inv_txfm_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(Trans4x4WHT, AccuracyCheck) {
|
||||||
|
RunAccuracyCheck(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(Trans4x4WHT, CoeffCheck) {
|
||||||
|
RunCoeffCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(Trans4x4WHT, MemCheck) {
|
||||||
|
RunMemCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(Trans4x4WHT, InvAccuracyCheck) {
|
||||||
|
RunInvAccuracyCheck(0);
|
||||||
|
}
|
||||||
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
C, Trans4x4DCT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_10, 0, VPX_BITS_10, 16),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_12, 0, VPX_BITS_12, 16),
|
||||||
|
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c, 0, VPX_BITS_8, 16)));
|
||||||
|
#else
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
C, Trans4x4DCT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c, 0, VPX_BITS_8, 16)));
|
||||||
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
|
||||||
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
C, Trans4x4HT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vp10_highbd_fht4x4_c, &iht4x4_10, 0, VPX_BITS_10, 16),
|
||||||
|
make_tuple(&vp10_highbd_fht4x4_c, &iht4x4_10, 1, VPX_BITS_10, 16),
|
||||||
|
make_tuple(&vp10_highbd_fht4x4_c, &iht4x4_10, 2, VPX_BITS_10, 16),
|
||||||
|
make_tuple(&vp10_highbd_fht4x4_c, &iht4x4_10, 3, VPX_BITS_10, 16),
|
||||||
|
make_tuple(&vp10_highbd_fht4x4_c, &iht4x4_12, 0, VPX_BITS_12, 16),
|
||||||
|
make_tuple(&vp10_highbd_fht4x4_c, &iht4x4_12, 1, VPX_BITS_12, 16),
|
||||||
|
make_tuple(&vp10_highbd_fht4x4_c, &iht4x4_12, 2, VPX_BITS_12, 16),
|
||||||
|
make_tuple(&vp10_highbd_fht4x4_c, &iht4x4_12, 3, VPX_BITS_12, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_c, 0, VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_c, 1, VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_c, 2, VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_c, 3, VPX_BITS_8, 16)));
|
||||||
|
#else
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
C, Trans4x4HT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_c, 0, VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_c, 1, VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_c, 2, VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_c, 3, VPX_BITS_8, 16)));
|
||||||
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
|
||||||
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
C, Trans4x4WHT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vp10_highbd_fwht4x4_c, &iwht4x4_10, 0, VPX_BITS_10, 16),
|
||||||
|
make_tuple(&vp10_highbd_fwht4x4_c, &iwht4x4_12, 0, VPX_BITS_12, 16),
|
||||||
|
make_tuple(&vp10_fwht4x4_c, &vpx_iwht4x4_16_add_c, 0, VPX_BITS_8, 16)));
|
||||||
|
#else
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
C, Trans4x4WHT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vp10_fwht4x4_c, &vpx_iwht4x4_16_add_c, 0, VPX_BITS_8, 16)));
|
||||||
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
|
||||||
|
#if HAVE_NEON_ASM && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
NEON, Trans4x4DCT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_fdct4x4_c,
|
||||||
|
&vpx_idct4x4_16_add_neon, 0, VPX_BITS_8, 16)));
|
||||||
|
#endif // HAVE_NEON_ASM && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
|
#if HAVE_NEON && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
NEON, Trans4x4HT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_neon,
|
||||||
|
0, VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_neon,
|
||||||
|
1, VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_neon,
|
||||||
|
2, VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_neon,
|
||||||
|
3, VPX_BITS_8, 16)));
|
||||||
|
#endif // HAVE_NEON && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
|
#if HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE2, Trans4x4WHT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vp10_fwht4x4_c, &vpx_iwht4x4_16_add_c,
|
||||||
|
0, VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fwht4x4_c, &vpx_iwht4x4_16_add_sse2,
|
||||||
|
0, VPX_BITS_8, 16)));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_SSE2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE2, Trans4x4DCT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_fdct4x4_sse2,
|
||||||
|
&vpx_idct4x4_16_add_sse2, 0, VPX_BITS_8, 16)));
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE2, Trans4x4HT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vp10_fht4x4_sse2, &vp10_iht4x4_16_add_sse2, 0,
|
||||||
|
VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_sse2, &vp10_iht4x4_16_add_sse2, 1,
|
||||||
|
VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_sse2, &vp10_iht4x4_16_add_sse2, 2,
|
||||||
|
VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_sse2, &vp10_iht4x4_16_add_sse2, 3,
|
||||||
|
VPX_BITS_8, 16)));
|
||||||
|
#endif // HAVE_SSE2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
|
#if HAVE_SSE2 && CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE2, Trans4x4DCT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_10_sse2, 0,
|
||||||
|
VPX_BITS_10, 16),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_sse2, &idct4x4_10_sse2, 0,
|
||||||
|
VPX_BITS_10, 16),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_12_sse2, 0,
|
||||||
|
VPX_BITS_12, 16),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_sse2, &idct4x4_12_sse2, 0,
|
||||||
|
VPX_BITS_12, 16),
|
||||||
|
make_tuple(&vpx_fdct4x4_sse2, &vpx_idct4x4_16_add_c, 0,
|
||||||
|
VPX_BITS_8, 16)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE2, Trans4x4HT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vp10_fht4x4_sse2, &vp10_iht4x4_16_add_c,
|
||||||
|
0, VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_sse2, &vp10_iht4x4_16_add_c,
|
||||||
|
1, VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_sse2, &vp10_iht4x4_16_add_c,
|
||||||
|
2, VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_sse2, &vp10_iht4x4_16_add_c,
|
||||||
|
3, VPX_BITS_8, 16)));
|
||||||
|
#endif // HAVE_SSE2 && CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
|
#if HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
MSA, Trans4x4DCT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_fdct4x4_msa, &vpx_idct4x4_16_add_msa, 0,
|
||||||
|
VPX_BITS_8, 16)));
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
MSA, Trans4x4HT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vp10_fht4x4_msa, &vp10_iht4x4_16_add_msa, 0,
|
||||||
|
VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_msa, &vp10_iht4x4_16_add_msa, 1,
|
||||||
|
VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_msa, &vp10_iht4x4_16_add_msa, 2,
|
||||||
|
VPX_BITS_8, 16),
|
||||||
|
make_tuple(&vp10_fht4x4_msa, &vp10_iht4x4_16_add_msa, 3,
|
||||||
|
VPX_BITS_8, 16)));
|
||||||
|
#endif // HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
} // namespace
|
||||||
@@ -14,14 +14,14 @@
|
|||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vp9_rtcd.h"
|
#include "./vp10_rtcd.h"
|
||||||
#include "./vpx_dsp_rtcd.h"
|
#include "./vpx_dsp_rtcd.h"
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
#include "vp9/common/vp9_entropy.h"
|
#include "vp10/common/entropy.h"
|
||||||
#include "vp9/common/vp9_scan.h"
|
#include "vp10/common/scan.h"
|
||||||
#include "vpx/vpx_codec.h"
|
#include "vpx/vpx_codec.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
#include "vpx_ports/mem.h"
|
#include "vpx_ports/mem.h"
|
||||||
@@ -51,10 +51,10 @@ void reference_8x8_dct_1d(const double in[8], double out[8]) {
|
|||||||
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
||||||
for (int k = 0; k < 8; k++) {
|
for (int k = 0; k < 8; k++) {
|
||||||
out[k] = 0.0;
|
out[k] = 0.0;
|
||||||
for (int n = 0; n < 8; n++) {
|
for (int n = 0; n < 8; n++)
|
||||||
out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 16.0);
|
out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 16.0);
|
||||||
}
|
if (k == 0)
|
||||||
if (k == 0) out[k] = out[k] * kInvSqrt2;
|
out[k] = out[k] * kInvSqrt2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,73 +63,78 @@ void reference_8x8_dct_2d(const int16_t input[kNumCoeffs],
|
|||||||
// First transform columns
|
// First transform columns
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
double temp_in[8], temp_out[8];
|
double temp_in[8], temp_out[8];
|
||||||
for (int j = 0; j < 8; ++j) temp_in[j] = input[j * 8 + i];
|
for (int j = 0; j < 8; ++j)
|
||||||
|
temp_in[j] = input[j*8 + i];
|
||||||
reference_8x8_dct_1d(temp_in, temp_out);
|
reference_8x8_dct_1d(temp_in, temp_out);
|
||||||
for (int j = 0; j < 8; ++j) output[j * 8 + i] = temp_out[j];
|
for (int j = 0; j < 8; ++j)
|
||||||
|
output[j * 8 + i] = temp_out[j];
|
||||||
}
|
}
|
||||||
// Then transform rows
|
// Then transform rows
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
double temp_in[8], temp_out[8];
|
double temp_in[8], temp_out[8];
|
||||||
for (int j = 0; j < 8; ++j) temp_in[j] = output[j + i * 8];
|
for (int j = 0; j < 8; ++j)
|
||||||
|
temp_in[j] = output[j + i*8];
|
||||||
reference_8x8_dct_1d(temp_in, temp_out);
|
reference_8x8_dct_1d(temp_in, temp_out);
|
||||||
// Scale by some magic number
|
// Scale by some magic number
|
||||||
for (int j = 0; j < 8; ++j) output[j + i * 8] = temp_out[j] * 2;
|
for (int j = 0; j < 8; ++j)
|
||||||
|
output[j + i * 8] = temp_out[j] * 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void fdct8x8_ref(const int16_t *in, tran_low_t *out, int stride,
|
void fdct8x8_ref(const int16_t *in, tran_low_t *out, int stride,
|
||||||
int /*tx_type*/) {
|
int /*tx_type*/) {
|
||||||
vpx_fdct8x8_c(in, out, stride);
|
vpx_fdct8x8_c(in, out, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fht8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
void fht8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
||||||
vp9_fht8x8_c(in, out, stride, tx_type);
|
vp10_fht8x8_c(in, out, stride, tx_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
void idct8x8_10(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
vpx_highbd_idct8x8_64_add_c(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_12(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
vpx_highbd_idct8x8_64_add_c(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iht8x8_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
void iht8x8_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||||
vp9_highbd_iht8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 10);
|
vp10_highbd_iht8x8_64_add_c(in, out, stride, tx_type, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iht8x8_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
void iht8x8_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||||
vp9_highbd_iht8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 12);
|
vp10_highbd_iht8x8_64_add_c(in, out, stride, tx_type, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
|
|
||||||
void idct8x8_12_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_12_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
vpx_highbd_idct8x8_10_add_c(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_12_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_12_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
vpx_highbd_idct8x8_10_add_c(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_12_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_12_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
vpx_highbd_idct8x8_10_add_sse2(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_12_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_12_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
vpx_highbd_idct8x8_10_add_sse2(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_64_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_64_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_64_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
vpx_highbd_idct8x8_64_add_sse2(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_64_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_64_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_64_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
vpx_highbd_idct8x8_64_add_sse2(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
#endif // HAVE_SSE2
|
#endif // HAVE_SSE2
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
|
||||||
class FwdTrans8x8TestBase {
|
class FwdTrans8x8TestBase {
|
||||||
public:
|
public:
|
||||||
@@ -150,21 +155,19 @@ class FwdTrans8x8TestBase {
|
|||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
// Initialize a test block with input range [-255, 255].
|
// Initialize a test block with input range [-255, 255].
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j)
|
||||||
test_input_block[j] = ((rnd.Rand16() >> (16 - bit_depth_)) & mask_) -
|
test_input_block[j] = ((rnd.Rand16() >> (16 - bit_depth_)) & mask_) -
|
||||||
((rnd.Rand16() >> (16 - bit_depth_)) & mask_);
|
((rnd.Rand16() >> (16 - bit_depth_)) & mask_);
|
||||||
}
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunFwdTxfm(test_input_block, test_output_block, pitch_));
|
RunFwdTxfm(test_input_block, test_output_block, pitch_));
|
||||||
|
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j) {
|
||||||
if (test_output_block[j] < 0) {
|
if (test_output_block[j] < 0)
|
||||||
++count_sign_block[j][0];
|
++count_sign_block[j][0];
|
||||||
} else if (test_output_block[j] > 0) {
|
else if (test_output_block[j] > 0)
|
||||||
++count_sign_block[j][1];
|
++count_sign_block[j][1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j) {
|
||||||
const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
|
const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
|
||||||
@@ -174,28 +177,27 @@ class FwdTrans8x8TestBase {
|
|||||||
<< 1. * max_diff / count_test_block * 100 << "%"
|
<< 1. * max_diff / count_test_block * 100 << "%"
|
||||||
<< " for input range [-255, 255] at index " << j
|
<< " for input range [-255, 255] at index " << j
|
||||||
<< " count0: " << count_sign_block[j][0]
|
<< " count0: " << count_sign_block[j][0]
|
||||||
<< " count1: " << count_sign_block[j][1] << " diff: " << diff;
|
<< " count1: " << count_sign_block[j][1]
|
||||||
|
<< " diff: " << diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(count_sign_block, 0, sizeof(count_sign_block));
|
memset(count_sign_block, 0, sizeof(count_sign_block));
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
// Initialize a test block with input range [-mask_ / 16, mask_ / 16].
|
// Initialize a test block with input range [-mask_ / 16, mask_ / 16].
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j)
|
||||||
test_input_block[j] =
|
test_input_block[j] = ((rnd.Rand16() & mask_) >> 4) -
|
||||||
((rnd.Rand16() & mask_) >> 4) - ((rnd.Rand16() & mask_) >> 4);
|
((rnd.Rand16() & mask_) >> 4);
|
||||||
}
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunFwdTxfm(test_input_block, test_output_block, pitch_));
|
RunFwdTxfm(test_input_block, test_output_block, pitch_));
|
||||||
|
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j) {
|
||||||
if (test_output_block[j] < 0) {
|
if (test_output_block[j] < 0)
|
||||||
++count_sign_block[j][0];
|
++count_sign_block[j][0];
|
||||||
} else if (test_output_block[j] > 0) {
|
else if (test_output_block[j] > 0)
|
||||||
++count_sign_block[j][1];
|
++count_sign_block[j][1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j) {
|
||||||
const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
|
const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
|
||||||
@@ -205,7 +207,8 @@ class FwdTrans8x8TestBase {
|
|||||||
<< 1. * max_diff / count_test_block * 100 << "%"
|
<< 1. * max_diff / count_test_block * 100 << "%"
|
||||||
<< " for input range [-15, 15] at index " << j
|
<< " for input range [-15, 15] at index " << j
|
||||||
<< " count0: " << count_sign_block[j][0]
|
<< " count0: " << count_sign_block[j][0]
|
||||||
<< " count1: " << count_sign_block[j][1] << " diff: " << diff;
|
<< " count1: " << count_sign_block[j][1]
|
||||||
|
<< " diff: " << diff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,7 +221,7 @@ class FwdTrans8x8TestBase {
|
|||||||
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[64]);
|
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[64]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[64]);
|
DECLARE_ALIGNED(16, uint8_t, dst[64]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, src[64]);
|
DECLARE_ALIGNED(16, uint8_t, src[64]);
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[64]);
|
DECLARE_ALIGNED(16, uint16_t, dst16[64]);
|
||||||
DECLARE_ALIGNED(16, uint16_t, src16[64]);
|
DECLARE_ALIGNED(16, uint16_t, src16[64]);
|
||||||
#endif
|
#endif
|
||||||
@@ -230,7 +233,7 @@ class FwdTrans8x8TestBase {
|
|||||||
src[j] = rnd.Rand8();
|
src[j] = rnd.Rand8();
|
||||||
dst[j] = rnd.Rand8();
|
dst[j] = rnd.Rand8();
|
||||||
test_input_block[j] = src[j] - dst[j];
|
test_input_block[j] = src[j] - dst[j];
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
src16[j] = rnd.Rand16() & mask_;
|
src16[j] = rnd.Rand16() & mask_;
|
||||||
dst16[j] = rnd.Rand16() & mask_;
|
dst16[j] = rnd.Rand16() & mask_;
|
||||||
@@ -253,23 +256,25 @@ class FwdTrans8x8TestBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
RunInvTxfm(test_temp_block, dst, pitch_));
|
||||||
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
const int diff =
|
const int diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
const int diff = dst[j] - src[j];
|
const int diff = dst[j] - src[j];
|
||||||
#endif
|
#endif
|
||||||
const int error = diff * diff;
|
const int error = diff * diff;
|
||||||
if (max_error < error) max_error = error;
|
if (max_error < error)
|
||||||
|
max_error = error;
|
||||||
total_error += error;
|
total_error += error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,7 +299,7 @@ class FwdTrans8x8TestBase {
|
|||||||
DECLARE_ALIGNED(16, tran_low_t, ref_temp_block[64]);
|
DECLARE_ALIGNED(16, tran_low_t, ref_temp_block[64]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[64]);
|
DECLARE_ALIGNED(16, uint8_t, dst[64]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, src[64]);
|
DECLARE_ALIGNED(16, uint8_t, src[64]);
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[64]);
|
DECLARE_ALIGNED(16, uint16_t, dst16[64]);
|
||||||
DECLARE_ALIGNED(16, uint16_t, src16[64]);
|
DECLARE_ALIGNED(16, uint16_t, src16[64]);
|
||||||
#endif
|
#endif
|
||||||
@@ -314,7 +319,7 @@ class FwdTrans8x8TestBase {
|
|||||||
dst[j] = rnd.Rand8() % 2 ? 255 : 0;
|
dst[j] = rnd.Rand8() % 2 ? 255 : 0;
|
||||||
}
|
}
|
||||||
test_input_block[j] = src[j] - dst[j];
|
test_input_block[j] = src[j] - dst[j];
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
src16[j] = mask_;
|
src16[j] = mask_;
|
||||||
@@ -336,23 +341,25 @@ class FwdTrans8x8TestBase {
|
|||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
fwd_txfm_ref(test_input_block, ref_temp_block, pitch_, tx_type_));
|
fwd_txfm_ref(test_input_block, ref_temp_block, pitch_, tx_type_));
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
RunInvTxfm(test_temp_block, dst, pitch_));
|
||||||
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
const int diff =
|
const int diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
const int diff = dst[j] - src[j];
|
const int diff = dst[j] - src[j];
|
||||||
#endif
|
#endif
|
||||||
const int error = diff * diff;
|
const int error = diff * diff;
|
||||||
if (max_error < error) max_error = error;
|
if (max_error < error)
|
||||||
|
max_error = error;
|
||||||
total_error += error;
|
total_error += error;
|
||||||
|
|
||||||
const int coeff_diff = test_temp_block[j] - ref_temp_block[j];
|
const int coeff_diff = test_temp_block[j] - ref_temp_block[j];
|
||||||
@@ -380,7 +387,7 @@ class FwdTrans8x8TestBase {
|
|||||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||||
#endif
|
#endif
|
||||||
@@ -394,7 +401,7 @@ class FwdTrans8x8TestBase {
|
|||||||
src[j] = rnd.Rand8() % 2 ? 255 : 0;
|
src[j] = rnd.Rand8() % 2 ? 255 : 0;
|
||||||
dst[j] = src[j] > 0 ? 0 : 255;
|
dst[j] = src[j] > 0 ? 0 : 255;
|
||||||
in[j] = src[j] - dst[j];
|
in[j] = src[j] - dst[j];
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
src16[j] = rnd.Rand8() % 2 ? mask_ : 0;
|
src16[j] = rnd.Rand8() % 2 ? mask_ : 0;
|
||||||
dst16[j] = src16[j] > 0 ? 0 : mask_;
|
dst16[j] = src16[j] > 0 ? 0 : mask_;
|
||||||
@@ -404,21 +411,20 @@ class FwdTrans8x8TestBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reference_8x8_dct_2d(in, out_r);
|
reference_8x8_dct_2d(in, out_r);
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
|
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
|
||||||
}
|
|
||||||
|
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
||||||
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_));
|
pitch_));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
const int diff =
|
const int diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
@@ -426,7 +432,8 @@ class FwdTrans8x8TestBase {
|
|||||||
#endif
|
#endif
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_GE(1u << 2 * (bit_depth_ - 8), error)
|
EXPECT_GE(1u << 2 * (bit_depth_ - 8), error)
|
||||||
<< "Error: 8x8 IDCT has error " << error << " at index " << j;
|
<< "Error: 8x8 IDCT has error " << error
|
||||||
|
<< " at index " << j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -442,21 +449,20 @@ class FwdTrans8x8TestBase {
|
|||||||
double out_r[kNumCoeffs];
|
double out_r[kNumCoeffs];
|
||||||
|
|
||||||
// Initialize a test block with input range [-mask_, mask_].
|
// Initialize a test block with input range [-mask_, mask_].
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
in[j] = rnd.Rand8() % 2 == 0 ? mask_ : -mask_;
|
in[j] = rnd.Rand8() % 2 == 0 ? mask_ : -mask_;
|
||||||
}
|
|
||||||
|
|
||||||
RunFwdTxfm(in, coeff, pitch_);
|
RunFwdTxfm(in, coeff, pitch_);
|
||||||
reference_8x8_dct_2d(in, out_r);
|
reference_8x8_dct_2d(in, out_r);
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
coeff_r[j] = static_cast<tran_low_t>(round(out_r[j]));
|
coeff_r[j] = static_cast<tran_low_t>(round(out_r[j]));
|
||||||
}
|
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
const int32_t diff = coeff[j] - coeff_r[j];
|
const int32_t diff = coeff[j] - coeff_r[j];
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_GE(9u << 2 * (bit_depth_ - 8), error)
|
EXPECT_GE(9u << 2 * (bit_depth_ - 8), error)
|
||||||
<< "Error: 8x8 DCT has error " << error << " at index " << j;
|
<< "Error: 8x8 DCT has error " << error
|
||||||
|
<< " at index " << j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -468,11 +474,11 @@ class FwdTrans8x8TestBase {
|
|||||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]);
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]);
|
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]);
|
||||||
#endif
|
#endif
|
||||||
const int16_t *scan = vp9_default_scan_orders[TX_8X8].scan;
|
const int16_t *scan = vp10_default_scan_orders[TX_8X8].scan;
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
@@ -485,7 +491,7 @@ class FwdTrans8x8TestBase {
|
|||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
dst[j] = 0;
|
dst[j] = 0;
|
||||||
ref[j] = 0;
|
ref[j] = 0;
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
dst16[j] = 0;
|
dst16[j] = 0;
|
||||||
ref16[j] = 0;
|
ref16[j] = 0;
|
||||||
@@ -495,16 +501,16 @@ class FwdTrans8x8TestBase {
|
|||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ref_txfm(coeff, ref, pitch_);
|
ref_txfm(coeff, ref, pitch_);
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ref_txfm(coeff, CAST_TO_BYTEPTR(ref16), pitch_);
|
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
||||||
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_));
|
pitch_));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
const int diff =
|
const int diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j];
|
||||||
#else
|
#else
|
||||||
@@ -512,7 +518,8 @@ class FwdTrans8x8TestBase {
|
|||||||
#endif
|
#endif
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_EQ(0u, error)
|
EXPECT_EQ(0u, error)
|
||||||
<< "Error: 8x8 IDCT has error " << error << " at index " << j;
|
<< "Error: 8x8 IDCT has error " << error
|
||||||
|
<< " at index " << j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -523,7 +530,8 @@ class FwdTrans8x8TestBase {
|
|||||||
int mask_;
|
int mask_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FwdTrans8x8DCT : public FwdTrans8x8TestBase,
|
class FwdTrans8x8DCT
|
||||||
|
: public FwdTrans8x8TestBase,
|
||||||
public ::testing::TestWithParam<Dct8x8Param> {
|
public ::testing::TestWithParam<Dct8x8Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~FwdTrans8x8DCT() {}
|
virtual ~FwdTrans8x8DCT() {}
|
||||||
@@ -552,17 +560,28 @@ class FwdTrans8x8DCT : public FwdTrans8x8TestBase,
|
|||||||
IdctFunc inv_txfm_;
|
IdctFunc inv_txfm_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(FwdTrans8x8DCT, SignBiasCheck) { RunSignBiasCheck(); }
|
TEST_P(FwdTrans8x8DCT, SignBiasCheck) {
|
||||||
|
RunSignBiasCheck();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(FwdTrans8x8DCT, RoundTripErrorCheck) { RunRoundTripErrorCheck(); }
|
TEST_P(FwdTrans8x8DCT, RoundTripErrorCheck) {
|
||||||
|
RunRoundTripErrorCheck();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(FwdTrans8x8DCT, ExtremalCheck) { RunExtremalCheck(); }
|
TEST_P(FwdTrans8x8DCT, ExtremalCheck) {
|
||||||
|
RunExtremalCheck();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(FwdTrans8x8DCT, FwdAccuracyCheck) { RunFwdAccuracyCheck(); }
|
TEST_P(FwdTrans8x8DCT, FwdAccuracyCheck) {
|
||||||
|
RunFwdAccuracyCheck();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(FwdTrans8x8DCT, InvAccuracyCheck) { RunInvAccuracyCheck(); }
|
TEST_P(FwdTrans8x8DCT, InvAccuracyCheck) {
|
||||||
|
RunInvAccuracyCheck();
|
||||||
|
}
|
||||||
|
|
||||||
class FwdTrans8x8HT : public FwdTrans8x8TestBase,
|
class FwdTrans8x8HT
|
||||||
|
: public FwdTrans8x8TestBase,
|
||||||
public ::testing::TestWithParam<Ht8x8Param> {
|
public ::testing::TestWithParam<Ht8x8Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~FwdTrans8x8HT() {}
|
virtual ~FwdTrans8x8HT() {}
|
||||||
@@ -591,13 +610,20 @@ class FwdTrans8x8HT : public FwdTrans8x8TestBase,
|
|||||||
IhtFunc inv_txfm_;
|
IhtFunc inv_txfm_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(FwdTrans8x8HT, SignBiasCheck) { RunSignBiasCheck(); }
|
TEST_P(FwdTrans8x8HT, SignBiasCheck) {
|
||||||
|
RunSignBiasCheck();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(FwdTrans8x8HT, RoundTripErrorCheck) { RunRoundTripErrorCheck(); }
|
TEST_P(FwdTrans8x8HT, RoundTripErrorCheck) {
|
||||||
|
RunRoundTripErrorCheck();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(FwdTrans8x8HT, ExtremalCheck) { RunExtremalCheck(); }
|
TEST_P(FwdTrans8x8HT, ExtremalCheck) {
|
||||||
|
RunExtremalCheck();
|
||||||
|
}
|
||||||
|
|
||||||
class InvTrans8x8DCT : public FwdTrans8x8TestBase,
|
class InvTrans8x8DCT
|
||||||
|
: public FwdTrans8x8TestBase,
|
||||||
public ::testing::TestWithParam<Idct8x8Param> {
|
public ::testing::TestWithParam<Idct8x8Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~InvTrans8x8DCT() {}
|
virtual ~InvTrans8x8DCT() {}
|
||||||
@@ -630,7 +656,7 @@ TEST_P(InvTrans8x8DCT, CompareReference) {
|
|||||||
|
|
||||||
using std::tr1::make_tuple;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, FwdTrans8x8DCT,
|
C, FwdTrans8x8DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
@@ -638,129 +664,132 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_10, 0, VPX_BITS_10),
|
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_10, 0, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_12, 0, VPX_BITS_12)));
|
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_12, 0, VPX_BITS_12)));
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(C, FwdTrans8x8DCT,
|
INSTANTIATE_TEST_CASE_P(
|
||||||
::testing::Values(make_tuple(&vpx_fdct8x8_c,
|
C, FwdTrans8x8DCT,
|
||||||
&vpx_idct8x8_64_add_c, 0,
|
::testing::Values(
|
||||||
VPX_BITS_8)));
|
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c, 0, VPX_BITS_8)));
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, FwdTrans8x8HT,
|
C, FwdTrans8x8HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 0, VPX_BITS_8),
|
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 0, VPX_BITS_10),
|
make_tuple(&vp10_highbd_fht8x8_c, &iht8x8_10, 0, VPX_BITS_10),
|
||||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 1, VPX_BITS_10),
|
make_tuple(&vp10_highbd_fht8x8_c, &iht8x8_10, 1, VPX_BITS_10),
|
||||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 2, VPX_BITS_10),
|
make_tuple(&vp10_highbd_fht8x8_c, &iht8x8_10, 2, VPX_BITS_10),
|
||||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 3, VPX_BITS_10),
|
make_tuple(&vp10_highbd_fht8x8_c, &iht8x8_10, 3, VPX_BITS_10),
|
||||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 0, VPX_BITS_12),
|
make_tuple(&vp10_highbd_fht8x8_c, &iht8x8_12, 0, VPX_BITS_12),
|
||||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 1, VPX_BITS_12),
|
make_tuple(&vp10_highbd_fht8x8_c, &iht8x8_12, 1, VPX_BITS_12),
|
||||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 2, VPX_BITS_12),
|
make_tuple(&vp10_highbd_fht8x8_c, &iht8x8_12, 2, VPX_BITS_12),
|
||||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 3, VPX_BITS_12),
|
make_tuple(&vp10_highbd_fht8x8_c, &iht8x8_12, 3, VPX_BITS_12),
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8),
|
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_c, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8),
|
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_c, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, FwdTrans8x8HT,
|
C, FwdTrans8x8HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 0, VPX_BITS_8),
|
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8),
|
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_c, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8),
|
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_c, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
|
||||||
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_NEON_ASM && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(NEON, FwdTrans8x8DCT,
|
INSTANTIATE_TEST_CASE_P(
|
||||||
::testing::Values(make_tuple(&vpx_fdct8x8_neon,
|
NEON, FwdTrans8x8DCT,
|
||||||
&vpx_idct8x8_64_add_neon,
|
::testing::Values(
|
||||||
0, VPX_BITS_8)));
|
make_tuple(&vpx_fdct8x8_neon, &vpx_idct8x8_64_add_neon, 0,
|
||||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
VPX_BITS_8)));
|
||||||
|
#endif // HAVE_NEON_ASM && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
|
#if HAVE_NEON && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, FwdTrans8x8HT,
|
NEON, FwdTrans8x8HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 0, VPX_BITS_8),
|
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_neon, 0, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 1, VPX_BITS_8),
|
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_neon, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 2, VPX_BITS_8),
|
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_neon, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 3, VPX_BITS_8)));
|
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_neon, 3, VPX_BITS_8)));
|
||||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
#endif // HAVE_NEON && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
|
||||||
|
|
||||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, FwdTrans8x8DCT,
|
INSTANTIATE_TEST_CASE_P(
|
||||||
::testing::Values(make_tuple(&vpx_fdct8x8_sse2,
|
SSE2, FwdTrans8x8DCT,
|
||||||
&vpx_idct8x8_64_add_sse2,
|
::testing::Values(
|
||||||
0, VPX_BITS_8)));
|
make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_sse2, 0,
|
||||||
|
VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, FwdTrans8x8HT,
|
SSE2, FwdTrans8x8HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 0, VPX_BITS_8),
|
make_tuple(&vp10_fht8x8_sse2, &vp10_iht8x8_64_add_sse2,
|
||||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 1, VPX_BITS_8),
|
0, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 2, VPX_BITS_8),
|
make_tuple(&vp10_fht8x8_sse2, &vp10_iht8x8_64_add_sse2,
|
||||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 3, VPX_BITS_8)));
|
1, VPX_BITS_8),
|
||||||
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
make_tuple(&vp10_fht8x8_sse2, &vp10_iht8x8_64_add_sse2,
|
||||||
|
2, VPX_BITS_8),
|
||||||
|
make_tuple(&vp10_fht8x8_sse2, &vp10_iht8x8_64_add_sse2,
|
||||||
|
3, VPX_BITS_8)));
|
||||||
|
#endif // HAVE_SSE2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, FwdTrans8x8DCT,
|
SSE2, FwdTrans8x8DCT,
|
||||||
::testing::Values(make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_c, 0,
|
::testing::Values(
|
||||||
VPX_BITS_8),
|
make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_64_add_10_sse2,
|
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||||
12, VPX_BITS_10),
|
&idct8x8_64_add_10_sse2, 12, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct8x8_sse2,
|
make_tuple(&vpx_highbd_fdct8x8_sse2,
|
||||||
&idct8x8_64_add_10_sse2, 12, VPX_BITS_10),
|
&idct8x8_64_add_10_sse2, 12, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_64_add_12_sse2,
|
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||||
12, VPX_BITS_12),
|
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12),
|
||||||
make_tuple(&vpx_highbd_fdct8x8_sse2,
|
make_tuple(&vpx_highbd_fdct8x8_sse2,
|
||||||
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12)));
|
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, FwdTrans8x8HT,
|
SSE2, FwdTrans8x8HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_c, 0, VPX_BITS_8),
|
make_tuple(&vp10_fht8x8_sse2, &vp10_iht8x8_64_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8),
|
make_tuple(&vp10_fht8x8_sse2, &vp10_iht8x8_64_add_c, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8),
|
make_tuple(&vp10_fht8x8_sse2, &vp10_iht8x8_64_add_c, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
make_tuple(&vp10_fht8x8_sse2, &vp10_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
||||||
|
|
||||||
// Optimizations take effect at a threshold of 6201, so we use a value close to
|
// Optimizations take effect at a threshold of 6201, so we use a value close to
|
||||||
// that to test both branches.
|
// that to test both branches.
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, InvTrans8x8DCT,
|
SSE2, InvTrans8x8DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&idct8x8_12_add_10_c, &idct8x8_12_add_10_sse2, 6225,
|
make_tuple(&idct8x8_10_add_10_c,
|
||||||
VPX_BITS_10),
|
&idct8x8_10_add_10_sse2, 6225, VPX_BITS_10),
|
||||||
make_tuple(&idct8x8_10, &idct8x8_64_add_10_sse2, 6225, VPX_BITS_10),
|
make_tuple(&idct8x8_10,
|
||||||
make_tuple(&idct8x8_12_add_12_c, &idct8x8_12_add_12_sse2, 6225,
|
&idct8x8_64_add_10_sse2, 6225, VPX_BITS_10),
|
||||||
VPX_BITS_12),
|
make_tuple(&idct8x8_10_add_12_c,
|
||||||
make_tuple(&idct8x8_12, &idct8x8_64_add_12_sse2, 6225, VPX_BITS_12)));
|
&idct8x8_10_add_12_sse2, 6225, VPX_BITS_12),
|
||||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
make_tuple(&idct8x8_12,
|
||||||
|
&idct8x8_64_add_12_sse2, 6225, VPX_BITS_12)));
|
||||||
|
#endif // HAVE_SSE2 && CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_VP9_HIGHBITDEPTH && \
|
#if HAVE_SSSE3 && ARCH_X86_64 && \
|
||||||
!CONFIG_EMULATE_HARDWARE
|
!CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(SSSE3, FwdTrans8x8DCT,
|
INSTANTIATE_TEST_CASE_P(
|
||||||
::testing::Values(make_tuple(&vpx_fdct8x8_ssse3,
|
SSSE3, FwdTrans8x8DCT,
|
||||||
&vpx_idct8x8_64_add_sse2,
|
::testing::Values(
|
||||||
0, VPX_BITS_8)));
|
make_tuple(&vpx_fdct8x8_ssse3, &vpx_idct8x8_64_add_ssse3, 0,
|
||||||
|
VPX_BITS_8)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(MSA, FwdTrans8x8DCT,
|
INSTANTIATE_TEST_CASE_P(
|
||||||
::testing::Values(make_tuple(&vpx_fdct8x8_msa,
|
MSA, FwdTrans8x8DCT,
|
||||||
&vpx_idct8x8_64_add_msa, 0,
|
::testing::Values(
|
||||||
VPX_BITS_8)));
|
make_tuple(&vpx_fdct8x8_msa, &vpx_idct8x8_64_add_msa, 0, VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
MSA, FwdTrans8x8HT,
|
MSA, FwdTrans8x8HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 0, VPX_BITS_8),
|
make_tuple(&vp10_fht8x8_msa, &vp10_iht8x8_64_add_msa, 0, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 1, VPX_BITS_8),
|
make_tuple(&vp10_fht8x8_msa, &vp10_iht8x8_64_add_msa, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 2, VPX_BITS_8),
|
make_tuple(&vp10_fht8x8_msa, &vp10_iht8x8_64_add_msa, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 3, VPX_BITS_8)));
|
make_tuple(&vp10_fht8x8_msa, &vp10_iht8x8_64_add_msa, 3, VPX_BITS_8)));
|
||||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
INSTANTIATE_TEST_CASE_P(VSX, FwdTrans8x8DCT,
|
|
||||||
::testing::Values(make_tuple(&vpx_fdct8x8_c,
|
|
||||||
&vpx_idct8x8_64_add_vsx, 0,
|
|
||||||
VPX_BITS_8)));
|
|
||||||
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -13,11 +13,12 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class VP9FrameSizeTestsLarge : public ::libvpx_test::EncoderTest,
|
class VP9FrameSizeTestsLarge
|
||||||
|
: public ::libvpx_test::EncoderTest,
|
||||||
public ::testing::Test {
|
public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
VP9FrameSizeTestsLarge()
|
VP9FrameSizeTestsLarge() : EncoderTest(&::libvpx_test::kVP10),
|
||||||
: EncoderTest(&::libvpx_test::kVP9), expected_res_(VPX_CODEC_OK) {}
|
expected_res_(VPX_CODEC_OK) {}
|
||||||
virtual ~VP9FrameSizeTestsLarge() {}
|
virtual ~VP9FrameSizeTestsLarge() {}
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
|
|||||||
65
test/function_equivalence_test.h
Normal file
65
test/function_equivalence_test.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 The WebM project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TEST_FUNCTION_EQUIVALENCE_TEST_H_
|
||||||
|
#define TEST_FUNCTION_EQUIVALENCE_TEST_H_
|
||||||
|
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
#include "test/acm_random.h"
|
||||||
|
#include "test/clear_system_state.h"
|
||||||
|
#include "test/util.h"
|
||||||
|
|
||||||
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
|
namespace libvpx_test {
|
||||||
|
// Base class for tests that compare 2 implementations of the same function
|
||||||
|
// for equivalence. The template parameter should be pointer to a function
|
||||||
|
// that is being tested.
|
||||||
|
//
|
||||||
|
// The test takes a 3-parameters encapsulating struct 'FuncParam', containing:
|
||||||
|
// - Pointer to reference function
|
||||||
|
// - Pointer to tested function
|
||||||
|
// - Integer bit depth (default to 0).
|
||||||
|
//
|
||||||
|
// These values are then accessible in the tests as member of params_:
|
||||||
|
// params_.ref_func, params_.tst_func, and params_.bit_depth.
|
||||||
|
//
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct FuncParam {
|
||||||
|
FuncParam(T ref = NULL, T tst = NULL, int bit_depth = 0)
|
||||||
|
: ref_func(ref), tst_func(tst), bit_depth(bit_depth) {}
|
||||||
|
T ref_func;
|
||||||
|
T tst_func;
|
||||||
|
int bit_depth;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class FunctionEquivalenceTest : public ::testing::TestWithParam<FuncParam<T> > {
|
||||||
|
public:
|
||||||
|
FunctionEquivalenceTest() : rng_(ACMRandom::DeterministicSeed()) {}
|
||||||
|
|
||||||
|
virtual ~FunctionEquivalenceTest() {}
|
||||||
|
|
||||||
|
virtual void SetUp() {
|
||||||
|
params_ = this->GetParam();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void TearDown() {
|
||||||
|
libvpx_test::ClearSystemState();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ACMRandom rng_;
|
||||||
|
FuncParam<T> params_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace libvpx_test
|
||||||
|
#endif // TEST_FUNCTION_EQUIVALENCE_TEST_H_
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
#include "./vpx_dsp_rtcd.h"
|
||||||
#include "vpx_ports/vpx_timer.h"
|
|
||||||
|
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
@@ -22,8 +21,7 @@ namespace {
|
|||||||
|
|
||||||
using ::libvpx_test::ACMRandom;
|
using ::libvpx_test::ACMRandom;
|
||||||
|
|
||||||
typedef void (*HadamardFunc)(const int16_t *a, ptrdiff_t a_stride,
|
typedef void (*HadamardFunc)(const int16_t *a, int a_stride, int16_t *b);
|
||||||
tran_low_t *b);
|
|
||||||
|
|
||||||
void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
||||||
int16_t b[8];
|
int16_t b[8];
|
||||||
@@ -48,16 +46,18 @@ void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
|||||||
out[5] = c[3] - c[7];
|
out[5] = c[3] - c[7];
|
||||||
}
|
}
|
||||||
|
|
||||||
void reference_hadamard8x8(const int16_t *a, int a_stride, tran_low_t *b) {
|
void reference_hadamard8x8(const int16_t *a, int a_stride, int16_t *b) {
|
||||||
int16_t buf[64];
|
int16_t buf[64];
|
||||||
int16_t buf2[64];
|
for (int i = 0; i < 8; ++i) {
|
||||||
for (int i = 0; i < 8; ++i) hadamard_loop(a + i, a_stride, buf + i * 8);
|
hadamard_loop(a + i, a_stride, buf + i * 8);
|
||||||
for (int i = 0; i < 8; ++i) hadamard_loop(buf + i, 8, buf2 + i * 8);
|
|
||||||
|
|
||||||
for (int i = 0; i < 64; ++i) b[i] = (tran_low_t)buf2[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reference_hadamard16x16(const int16_t *a, int a_stride, tran_low_t *b) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
|
hadamard_loop(buf + i, 8, b + i * 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reference_hadamard16x16(const int16_t *a, int a_stride, int16_t *b) {
|
||||||
/* The source is a 16x16 block. The destination is rearranged to 8x32.
|
/* The source is a 16x16 block. The destination is rearranged to 8x32.
|
||||||
* Input is 9 bit. */
|
* Input is 9 bit. */
|
||||||
reference_hadamard8x8(a + 0 + 0 * a_stride, a_stride, b + 0);
|
reference_hadamard8x8(a + 0 + 0 * a_stride, a_stride, b + 0);
|
||||||
@@ -68,16 +68,16 @@ void reference_hadamard16x16(const int16_t *a, int a_stride, tran_low_t *b) {
|
|||||||
/* Overlay the 8x8 blocks and combine. */
|
/* Overlay the 8x8 blocks and combine. */
|
||||||
for (int i = 0; i < 64; ++i) {
|
for (int i = 0; i < 64; ++i) {
|
||||||
/* 8x8 steps the range up to 15 bits. */
|
/* 8x8 steps the range up to 15 bits. */
|
||||||
const tran_low_t a0 = b[0];
|
const int16_t a0 = b[0];
|
||||||
const tran_low_t a1 = b[64];
|
const int16_t a1 = b[64];
|
||||||
const tran_low_t a2 = b[128];
|
const int16_t a2 = b[128];
|
||||||
const tran_low_t a3 = b[192];
|
const int16_t a3 = b[192];
|
||||||
|
|
||||||
/* Prevent the result from escaping int16_t. */
|
/* Prevent the result from escaping int16_t. */
|
||||||
const tran_low_t b0 = (a0 + a1) >> 1;
|
const int16_t b0 = (a0 + a1) >> 1;
|
||||||
const tran_low_t b1 = (a0 - a1) >> 1;
|
const int16_t b1 = (a0 - a1) >> 1;
|
||||||
const tran_low_t b2 = (a2 + a3) >> 1;
|
const int16_t b2 = (a2 + a3) >> 1;
|
||||||
const tran_low_t b3 = (a2 - a3) >> 1;
|
const int16_t b3 = (a2 - a3) >> 1;
|
||||||
|
|
||||||
/* Store a 16 bit value. */
|
/* Store a 16 bit value. */
|
||||||
b[ 0] = b0 + b2;
|
b[ 0] = b0 + b2;
|
||||||
@@ -101,35 +101,12 @@ class HadamardTestBase : public ::testing::TestWithParam<HadamardFunc> {
|
|||||||
ACMRandom rnd_;
|
ACMRandom rnd_;
|
||||||
};
|
};
|
||||||
|
|
||||||
void HadamardSpeedTest(const char *name, HadamardFunc const func,
|
|
||||||
const int16_t *input, int stride, tran_low_t *output,
|
|
||||||
int times) {
|
|
||||||
int i;
|
|
||||||
vpx_usec_timer timer;
|
|
||||||
|
|
||||||
vpx_usec_timer_start(&timer);
|
|
||||||
for (i = 0; i < times; ++i) {
|
|
||||||
func(input, stride, output);
|
|
||||||
}
|
|
||||||
vpx_usec_timer_mark(&timer);
|
|
||||||
|
|
||||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
|
||||||
printf("%s[%12d runs]: %d us\n", name, times, elapsed_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
class Hadamard8x8Test : public HadamardTestBase {};
|
class Hadamard8x8Test : public HadamardTestBase {};
|
||||||
|
|
||||||
void HadamardSpeedTest8x8(HadamardFunc const func, int times) {
|
|
||||||
DECLARE_ALIGNED(16, int16_t, input[64]);
|
|
||||||
DECLARE_ALIGNED(16, tran_low_t, output[64]);
|
|
||||||
memset(input, 1, sizeof(input));
|
|
||||||
HadamardSpeedTest("Hadamard8x8", func, input, 8, output, times);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Hadamard8x8Test, CompareReferenceRandom) {
|
TEST_P(Hadamard8x8Test, CompareReferenceRandom) {
|
||||||
DECLARE_ALIGNED(16, int16_t, a[64]);
|
DECLARE_ALIGNED(16, int16_t, a[64]);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, b[64]);
|
DECLARE_ALIGNED(16, int16_t, b[64]);
|
||||||
tran_low_t b_ref[64];
|
int16_t b_ref[64];
|
||||||
for (int i = 0; i < 64; ++i) {
|
for (int i = 0; i < 64; ++i) {
|
||||||
a[i] = rnd_.Rand9Signed();
|
a[i] = rnd_.Rand9Signed();
|
||||||
}
|
}
|
||||||
@@ -147,8 +124,8 @@ TEST_P(Hadamard8x8Test, CompareReferenceRandom) {
|
|||||||
|
|
||||||
TEST_P(Hadamard8x8Test, VaryStride) {
|
TEST_P(Hadamard8x8Test, VaryStride) {
|
||||||
DECLARE_ALIGNED(16, int16_t, a[64 * 8]);
|
DECLARE_ALIGNED(16, int16_t, a[64 * 8]);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, b[64]);
|
DECLARE_ALIGNED(16, int16_t, b[64]);
|
||||||
tran_low_t b_ref[64];
|
int16_t b_ref[64];
|
||||||
for (int i = 0; i < 64 * 8; ++i) {
|
for (int i = 0; i < 64 * 8; ++i) {
|
||||||
a[i] = rnd_.Rand9Signed();
|
a[i] = rnd_.Rand9Signed();
|
||||||
}
|
}
|
||||||
@@ -167,12 +144,6 @@ TEST_P(Hadamard8x8Test, VaryStride) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(Hadamard8x8Test, DISABLED_Speed) {
|
|
||||||
HadamardSpeedTest8x8(h_func_, 10);
|
|
||||||
HadamardSpeedTest8x8(h_func_, 10000);
|
|
||||||
HadamardSpeedTest8x8(h_func_, 10000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(C, Hadamard8x8Test,
|
INSTANTIATE_TEST_CASE_P(C, Hadamard8x8Test,
|
||||||
::testing::Values(&vpx_hadamard_8x8_c));
|
::testing::Values(&vpx_hadamard_8x8_c));
|
||||||
|
|
||||||
@@ -191,33 +162,12 @@ INSTANTIATE_TEST_CASE_P(NEON, Hadamard8x8Test,
|
|||||||
::testing::Values(&vpx_hadamard_8x8_neon));
|
::testing::Values(&vpx_hadamard_8x8_neon));
|
||||||
#endif // HAVE_NEON
|
#endif // HAVE_NEON
|
||||||
|
|
||||||
// TODO(jingning): Remove highbitdepth flag when the SIMD functions are
|
|
||||||
// in place and turn on the unit test.
|
|
||||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
#if HAVE_MSA
|
|
||||||
INSTANTIATE_TEST_CASE_P(MSA, Hadamard8x8Test,
|
|
||||||
::testing::Values(&vpx_hadamard_8x8_msa));
|
|
||||||
#endif // HAVE_MSA
|
|
||||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
|
|
||||||
#if HAVE_VSX
|
|
||||||
INSTANTIATE_TEST_CASE_P(VSX, Hadamard8x8Test,
|
|
||||||
::testing::Values(&vpx_hadamard_8x8_vsx));
|
|
||||||
#endif // HAVE_VSX
|
|
||||||
|
|
||||||
class Hadamard16x16Test : public HadamardTestBase {};
|
class Hadamard16x16Test : public HadamardTestBase {};
|
||||||
|
|
||||||
void HadamardSpeedTest16x16(HadamardFunc const func, int times) {
|
|
||||||
DECLARE_ALIGNED(16, int16_t, input[256]);
|
|
||||||
DECLARE_ALIGNED(16, tran_low_t, output[256]);
|
|
||||||
memset(input, 1, sizeof(input));
|
|
||||||
HadamardSpeedTest("Hadamard16x16", func, input, 16, output, times);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Hadamard16x16Test, CompareReferenceRandom) {
|
TEST_P(Hadamard16x16Test, CompareReferenceRandom) {
|
||||||
DECLARE_ALIGNED(16, int16_t, a[16 * 16]);
|
DECLARE_ALIGNED(16, int16_t, a[16 * 16]);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, b[16 * 16]);
|
DECLARE_ALIGNED(16, int16_t, b[16 * 16]);
|
||||||
tran_low_t b_ref[16 * 16];
|
int16_t b_ref[16 * 16];
|
||||||
for (int i = 0; i < 16 * 16; ++i) {
|
for (int i = 0; i < 16 * 16; ++i) {
|
||||||
a[i] = rnd_.Rand9Signed();
|
a[i] = rnd_.Rand9Signed();
|
||||||
}
|
}
|
||||||
@@ -235,8 +185,8 @@ TEST_P(Hadamard16x16Test, CompareReferenceRandom) {
|
|||||||
|
|
||||||
TEST_P(Hadamard16x16Test, VaryStride) {
|
TEST_P(Hadamard16x16Test, VaryStride) {
|
||||||
DECLARE_ALIGNED(16, int16_t, a[16 * 16 * 8]);
|
DECLARE_ALIGNED(16, int16_t, a[16 * 16 * 8]);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, b[16 * 16]);
|
DECLARE_ALIGNED(16, int16_t, b[16 * 16]);
|
||||||
tran_low_t b_ref[16 * 16];
|
int16_t b_ref[16 * 16];
|
||||||
for (int i = 0; i < 16 * 16 * 8; ++i) {
|
for (int i = 0; i < 16 * 16 * 8; ++i) {
|
||||||
a[i] = rnd_.Rand9Signed();
|
a[i] = rnd_.Rand9Signed();
|
||||||
}
|
}
|
||||||
@@ -255,12 +205,6 @@ TEST_P(Hadamard16x16Test, VaryStride) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(Hadamard16x16Test, DISABLED_Speed) {
|
|
||||||
HadamardSpeedTest16x16(h_func_, 10);
|
|
||||||
HadamardSpeedTest16x16(h_func_, 10000);
|
|
||||||
HadamardSpeedTest16x16(h_func_, 10000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(C, Hadamard16x16Test,
|
INSTANTIATE_TEST_CASE_P(C, Hadamard16x16Test,
|
||||||
::testing::Values(&vpx_hadamard_16x16_c));
|
::testing::Values(&vpx_hadamard_16x16_c));
|
||||||
|
|
||||||
@@ -269,25 +213,8 @@ INSTANTIATE_TEST_CASE_P(SSE2, Hadamard16x16Test,
|
|||||||
::testing::Values(&vpx_hadamard_16x16_sse2));
|
::testing::Values(&vpx_hadamard_16x16_sse2));
|
||||||
#endif // HAVE_SSE2
|
#endif // HAVE_SSE2
|
||||||
|
|
||||||
#if HAVE_AVX2
|
|
||||||
INSTANTIATE_TEST_CASE_P(AVX2, Hadamard16x16Test,
|
|
||||||
::testing::Values(&vpx_hadamard_16x16_avx2));
|
|
||||||
#endif // HAVE_AVX2
|
|
||||||
|
|
||||||
#if HAVE_VSX
|
|
||||||
INSTANTIATE_TEST_CASE_P(VSX, Hadamard16x16Test,
|
|
||||||
::testing::Values(&vpx_hadamard_16x16_vsx));
|
|
||||||
#endif // HAVE_VSX
|
|
||||||
|
|
||||||
#if HAVE_NEON
|
#if HAVE_NEON
|
||||||
INSTANTIATE_TEST_CASE_P(NEON, Hadamard16x16Test,
|
INSTANTIATE_TEST_CASE_P(NEON, Hadamard16x16Test,
|
||||||
::testing::Values(&vpx_hadamard_16x16_neon));
|
::testing::Values(&vpx_hadamard_16x16_neon));
|
||||||
#endif // HAVE_NEON
|
#endif // HAVE_NEON
|
||||||
|
|
||||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
#if HAVE_MSA
|
|
||||||
INSTANTIATE_TEST_CASE_P(MSA, Hadamard16x16Test,
|
|
||||||
::testing::Values(&vpx_hadamard_16x16_msa));
|
|
||||||
#endif // HAVE_MSA
|
|
||||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
251
test/hbd_metrics_test.cc
Normal file
251
test/hbd_metrics_test.cc
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
/*
|
||||||
|
* 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 <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
#include "test/acm_random.h"
|
||||||
|
#include "test/util.h"
|
||||||
|
#include "./vpx_config.h"
|
||||||
|
#include "vpx_dsp/psnr.h"
|
||||||
|
#include "vpx_dsp/ssim.h"
|
||||||
|
#include "vpx_ports/mem.h"
|
||||||
|
#include "vpx_ports/msvc.h"
|
||||||
|
#include "vpx_scale/yv12config.h"
|
||||||
|
|
||||||
|
|
||||||
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
typedef double (*LBDMetricFunc)(const YV12_BUFFER_CONFIG *source,
|
||||||
|
const YV12_BUFFER_CONFIG *dest);
|
||||||
|
typedef double (*HBDMetricFunc)(const YV12_BUFFER_CONFIG *source,
|
||||||
|
const YV12_BUFFER_CONFIG *dest,
|
||||||
|
uint32_t in_bd, uint32_t bd);
|
||||||
|
|
||||||
|
double compute_hbd_psnr(const YV12_BUFFER_CONFIG *source,
|
||||||
|
const YV12_BUFFER_CONFIG *dest,
|
||||||
|
uint32_t in_bd, uint32_t bd) {
|
||||||
|
PSNR_STATS psnr;
|
||||||
|
vpx_calc_highbd_psnr(source, dest, &psnr, bd, in_bd);
|
||||||
|
return psnr.psnr[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
double compute_psnr(const YV12_BUFFER_CONFIG *source,
|
||||||
|
const YV12_BUFFER_CONFIG *dest) {
|
||||||
|
PSNR_STATS psnr;
|
||||||
|
vpx_calc_psnr(source, dest, &psnr);
|
||||||
|
return psnr.psnr[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
double compute_hbd_psnrhvs(const YV12_BUFFER_CONFIG *source,
|
||||||
|
const YV12_BUFFER_CONFIG *dest,
|
||||||
|
uint32_t in_bd, uint32_t bd) {
|
||||||
|
double tempy, tempu, tempv;
|
||||||
|
return vpx_psnrhvs(source, dest,
|
||||||
|
&tempy, &tempu, &tempv, bd, in_bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
double compute_psnrhvs(const YV12_BUFFER_CONFIG *source,
|
||||||
|
const YV12_BUFFER_CONFIG *dest) {
|
||||||
|
double tempy, tempu, tempv;
|
||||||
|
return vpx_psnrhvs(source, dest,
|
||||||
|
&tempy, &tempu, &tempv, 8, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
double compute_hbd_fastssim(const YV12_BUFFER_CONFIG *source,
|
||||||
|
const YV12_BUFFER_CONFIG *dest,
|
||||||
|
uint32_t in_bd, uint32_t bd) {
|
||||||
|
double tempy, tempu, tempv;
|
||||||
|
return vpx_calc_fastssim(source, dest,
|
||||||
|
&tempy, &tempu, &tempv, bd, in_bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
double compute_fastssim(const YV12_BUFFER_CONFIG *source,
|
||||||
|
const YV12_BUFFER_CONFIG *dest) {
|
||||||
|
double tempy, tempu, tempv;
|
||||||
|
return vpx_calc_fastssim(source, dest,
|
||||||
|
&tempy, &tempu, &tempv, 8, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
double compute_hbd_vpxssim(const YV12_BUFFER_CONFIG *source,
|
||||||
|
const YV12_BUFFER_CONFIG *dest,
|
||||||
|
uint32_t in_bd, uint32_t bd) {
|
||||||
|
double ssim, weight;
|
||||||
|
ssim = vpx_highbd_calc_ssim(source, dest, &weight, bd, in_bd);
|
||||||
|
return 100 * pow(ssim / weight, 8.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
double compute_vpxssim(const YV12_BUFFER_CONFIG *source,
|
||||||
|
const YV12_BUFFER_CONFIG *dest) {
|
||||||
|
double ssim, weight;
|
||||||
|
ssim = vpx_calc_ssim(source, dest, &weight);
|
||||||
|
return 100 * pow(ssim / weight, 8.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class HBDMetricsTestBase {
|
||||||
|
public:
|
||||||
|
virtual ~HBDMetricsTestBase() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void RunAccuracyCheck() {
|
||||||
|
const int width = 1920;
|
||||||
|
const int height = 1080;
|
||||||
|
int i = 0;
|
||||||
|
const uint8_t kPixFiller = 128;
|
||||||
|
YV12_BUFFER_CONFIG lbd_src, lbd_dst;
|
||||||
|
YV12_BUFFER_CONFIG hbd_src, hbd_dst;
|
||||||
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
|
double lbd_db, hbd_db;
|
||||||
|
|
||||||
|
memset(&lbd_src, 0, sizeof(lbd_src));
|
||||||
|
memset(&lbd_dst, 0, sizeof(lbd_dst));
|
||||||
|
memset(&hbd_src, 0, sizeof(hbd_src));
|
||||||
|
memset(&hbd_dst, 0, sizeof(hbd_dst));
|
||||||
|
|
||||||
|
vpx_alloc_frame_buffer(&lbd_src, width, height, 1, 1, 0, 32, 16);
|
||||||
|
vpx_alloc_frame_buffer(&lbd_dst, width, height, 1, 1, 0, 32, 16);
|
||||||
|
vpx_alloc_frame_buffer(&hbd_src, width, height, 1, 1, 1, 32, 16);
|
||||||
|
vpx_alloc_frame_buffer(&hbd_dst, width, height, 1, 1, 1, 32, 16);
|
||||||
|
|
||||||
|
memset(lbd_src.buffer_alloc, kPixFiller, lbd_src.buffer_alloc_sz);
|
||||||
|
while (i < lbd_src.buffer_alloc_sz) {
|
||||||
|
uint16_t spel, dpel;
|
||||||
|
spel = lbd_src.buffer_alloc[i];
|
||||||
|
// Create some distortion for dst buffer.
|
||||||
|
dpel = rnd.Rand8();
|
||||||
|
lbd_dst.buffer_alloc[i] = (uint8_t)dpel;
|
||||||
|
((uint16_t*)(hbd_src.buffer_alloc))[i] = spel << (bit_depth_ - 8);
|
||||||
|
((uint16_t*)(hbd_dst.buffer_alloc))[i] = dpel << (bit_depth_ - 8);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
lbd_db = lbd_metric_(&lbd_src, &lbd_dst);
|
||||||
|
hbd_db = hbd_metric_(&hbd_src, &hbd_dst, input_bit_depth_, bit_depth_);
|
||||||
|
EXPECT_LE(fabs(lbd_db - hbd_db), threshold_);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < lbd_src.buffer_alloc_sz) {
|
||||||
|
uint16_t dpel;
|
||||||
|
// Create some small distortion for dst buffer.
|
||||||
|
dpel = 120 + (rnd.Rand8() >> 4);
|
||||||
|
lbd_dst.buffer_alloc[i] = (uint8_t)dpel;
|
||||||
|
((uint16_t*)(hbd_dst.buffer_alloc))[i] = dpel << (bit_depth_ - 8);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
lbd_db = lbd_metric_(&lbd_src, &lbd_dst);
|
||||||
|
hbd_db = hbd_metric_(&hbd_src, &hbd_dst, input_bit_depth_, bit_depth_);
|
||||||
|
EXPECT_LE(fabs(lbd_db - hbd_db), threshold_);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < lbd_src.buffer_alloc_sz) {
|
||||||
|
uint16_t dpel;
|
||||||
|
// Create some small distortion for dst buffer.
|
||||||
|
dpel = 126 + (rnd.Rand8() >> 6);
|
||||||
|
lbd_dst.buffer_alloc[i] = (uint8_t)dpel;
|
||||||
|
((uint16_t*)(hbd_dst.buffer_alloc))[i] = dpel << (bit_depth_ - 8);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
lbd_db = lbd_metric_(&lbd_src, &lbd_dst);
|
||||||
|
hbd_db = hbd_metric_(&hbd_src, &hbd_dst, input_bit_depth_, bit_depth_);
|
||||||
|
EXPECT_LE(fabs(lbd_db - hbd_db), threshold_);
|
||||||
|
|
||||||
|
vpx_free_frame_buffer(&lbd_src);
|
||||||
|
vpx_free_frame_buffer(&lbd_dst);
|
||||||
|
vpx_free_frame_buffer(&hbd_src);
|
||||||
|
vpx_free_frame_buffer(&hbd_dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
int input_bit_depth_;
|
||||||
|
int bit_depth_;
|
||||||
|
double threshold_;
|
||||||
|
LBDMetricFunc lbd_metric_;
|
||||||
|
HBDMetricFunc hbd_metric_;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::tr1::tuple<LBDMetricFunc,
|
||||||
|
HBDMetricFunc, int, int, double> MetricTestTParam;
|
||||||
|
class HBDMetricsTest
|
||||||
|
: public HBDMetricsTestBase,
|
||||||
|
public ::testing::TestWithParam<MetricTestTParam> {
|
||||||
|
public:
|
||||||
|
virtual void SetUp() {
|
||||||
|
lbd_metric_ = GET_PARAM(0);
|
||||||
|
hbd_metric_ = GET_PARAM(1);
|
||||||
|
input_bit_depth_ = GET_PARAM(2);
|
||||||
|
bit_depth_ = GET_PARAM(3);
|
||||||
|
threshold_ = GET_PARAM(4);
|
||||||
|
}
|
||||||
|
virtual void TearDown() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(HBDMetricsTest, RunAccuracyCheck) {
|
||||||
|
RunAccuracyCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow small variation due to floating point operations.
|
||||||
|
static const double kSsim_thresh = 0.001;
|
||||||
|
// Allow some additional errors accumulated in floating point operations.
|
||||||
|
static const double kFSsim_thresh = 0.03;
|
||||||
|
// Allow some extra variation due to rounding error accumulated in dct.
|
||||||
|
static const double kPhvs_thresh = 0.3;
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
VPXSSIM, HBDMetricsTest,
|
||||||
|
::testing::Values(
|
||||||
|
MetricTestTParam(&compute_vpxssim, &compute_hbd_vpxssim, 8, 10,
|
||||||
|
kSsim_thresh),
|
||||||
|
MetricTestTParam(&compute_vpxssim, &compute_hbd_vpxssim, 10, 10,
|
||||||
|
kPhvs_thresh),
|
||||||
|
MetricTestTParam(&compute_vpxssim, &compute_hbd_vpxssim, 8, 12,
|
||||||
|
kSsim_thresh),
|
||||||
|
MetricTestTParam(&compute_vpxssim, &compute_hbd_vpxssim, 12, 12,
|
||||||
|
kPhvs_thresh)));
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
FASTSSIM, HBDMetricsTest,
|
||||||
|
::testing::Values(
|
||||||
|
MetricTestTParam(&compute_fastssim, &compute_hbd_fastssim, 8, 10,
|
||||||
|
kFSsim_thresh),
|
||||||
|
MetricTestTParam(&compute_fastssim, &compute_hbd_fastssim, 10, 10,
|
||||||
|
kFSsim_thresh),
|
||||||
|
MetricTestTParam(&compute_fastssim, &compute_hbd_fastssim, 8, 12,
|
||||||
|
kFSsim_thresh),
|
||||||
|
MetricTestTParam(&compute_fastssim, &compute_hbd_fastssim, 12, 12,
|
||||||
|
kFSsim_thresh)));
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
PSNRHVS, HBDMetricsTest,
|
||||||
|
::testing::Values(
|
||||||
|
MetricTestTParam(&compute_psnrhvs, &compute_hbd_psnrhvs, 8, 10,
|
||||||
|
kPhvs_thresh),
|
||||||
|
MetricTestTParam(&compute_psnrhvs, &compute_hbd_psnrhvs, 10, 10,
|
||||||
|
kPhvs_thresh),
|
||||||
|
MetricTestTParam(&compute_psnrhvs, &compute_hbd_psnrhvs, 8, 12,
|
||||||
|
kPhvs_thresh),
|
||||||
|
MetricTestTParam(&compute_psnrhvs, &compute_hbd_psnrhvs, 12, 12,
|
||||||
|
kPhvs_thresh)));
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
PSNR, HBDMetricsTest,
|
||||||
|
::testing::Values(
|
||||||
|
MetricTestTParam(&compute_psnr, &compute_hbd_psnr, 8, 10,
|
||||||
|
kPhvs_thresh),
|
||||||
|
MetricTestTParam(&compute_psnr, &compute_hbd_psnr, 10, 10,
|
||||||
|
kPhvs_thresh),
|
||||||
|
MetricTestTParam(&compute_psnr, &compute_hbd_psnr, 8, 12,
|
||||||
|
kPhvs_thresh),
|
||||||
|
MetricTestTParam(&compute_psnr, &compute_hbd_psnr, 12, 12,
|
||||||
|
kPhvs_thresh)));
|
||||||
|
} // namespace
|
||||||
|
|
||||||
@@ -21,11 +21,14 @@ namespace libvpx_test {
|
|||||||
// so that we can do actual file encodes.
|
// so that we can do actual file encodes.
|
||||||
class I420VideoSource : public YUVVideoSource {
|
class I420VideoSource : public YUVVideoSource {
|
||||||
public:
|
public:
|
||||||
I420VideoSource(const std::string &file_name, unsigned int width,
|
I420VideoSource(const std::string &file_name,
|
||||||
unsigned int height, int rate_numerator, int rate_denominator,
|
unsigned int width, unsigned int height,
|
||||||
|
int rate_numerator, int rate_denominator,
|
||||||
unsigned int start, int limit)
|
unsigned int start, int limit)
|
||||||
: YUVVideoSource(file_name, VPX_IMG_FMT_I420, width, height,
|
: YUVVideoSource(file_name, VPX_IMG_FMT_I420,
|
||||||
rate_numerator, rate_denominator, start, limit) {}
|
width, height,
|
||||||
|
rate_numerator, rate_denominator,
|
||||||
|
start, limit) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace libvpx_test
|
} // namespace libvpx_test
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ void reference_dct_1d(double input[8], double output[8]) {
|
|||||||
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
||||||
for (int k = 0; k < 8; k++) {
|
for (int k = 0; k < 8; k++) {
|
||||||
output[k] = 0.0;
|
output[k] = 0.0;
|
||||||
for (int n = 0; n < 8; n++) {
|
for (int n = 0; n < 8; n++)
|
||||||
output[k] += input[n]*cos(kPi*(2*n+1)*k/16.0);
|
output[k] += input[n]*cos(kPi*(2*n+1)*k/16.0);
|
||||||
}
|
if (k == 0)
|
||||||
if (k == 0) output[k] = output[k] * kInvSqrt2;
|
output[k] = output[k]*kInvSqrt2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,19 +39,24 @@ void reference_dct_2d(int16_t input[64], double output[64]) {
|
|||||||
// First transform columns
|
// First transform columns
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
double temp_in[8], temp_out[8];
|
double temp_in[8], temp_out[8];
|
||||||
for (int j = 0; j < 8; ++j) temp_in[j] = input[j * 8 + i];
|
for (int j = 0; j < 8; ++j)
|
||||||
|
temp_in[j] = input[j*8 + i];
|
||||||
reference_dct_1d(temp_in, temp_out);
|
reference_dct_1d(temp_in, temp_out);
|
||||||
for (int j = 0; j < 8; ++j) output[j * 8 + i] = temp_out[j];
|
for (int j = 0; j < 8; ++j)
|
||||||
|
output[j*8 + i] = temp_out[j];
|
||||||
}
|
}
|
||||||
// Then transform rows
|
// Then transform rows
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
double temp_in[8], temp_out[8];
|
double temp_in[8], temp_out[8];
|
||||||
for (int j = 0; j < 8; ++j) temp_in[j] = output[j + i * 8];
|
for (int j = 0; j < 8; ++j)
|
||||||
|
temp_in[j] = output[j + i*8];
|
||||||
reference_dct_1d(temp_in, temp_out);
|
reference_dct_1d(temp_in, temp_out);
|
||||||
for (int j = 0; j < 8; ++j) output[j + i * 8] = temp_out[j];
|
for (int j = 0; j < 8; ++j)
|
||||||
|
output[j + i*8] = temp_out[j];
|
||||||
}
|
}
|
||||||
// Scale by some magic number
|
// Scale by some magic number
|
||||||
for (int i = 0; i < 64; ++i) output[i] *= 2;
|
for (int i = 0; i < 64; ++i)
|
||||||
|
output[i] *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(VP9Idct8x8Test, AccuracyCheck) {
|
TEST(VP9Idct8x8Test, AccuracyCheck) {
|
||||||
@@ -68,17 +73,18 @@ TEST(VP9Idct8x8Test, AccuracyCheck) {
|
|||||||
dst[j] = rnd.Rand8();
|
dst[j] = rnd.Rand8();
|
||||||
}
|
}
|
||||||
// Initialize a test block with input range [-255, 255].
|
// Initialize a test block with input range [-255, 255].
|
||||||
for (int j = 0; j < 64; ++j) input[j] = src[j] - dst[j];
|
for (int j = 0; j < 64; ++j)
|
||||||
|
input[j] = src[j] - dst[j];
|
||||||
|
|
||||||
reference_dct_2d(input, output_r);
|
reference_dct_2d(input, output_r);
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j)
|
||||||
coeff[j] = static_cast<tran_low_t>(round(output_r[j]));
|
coeff[j] = static_cast<tran_low_t>(round(output_r[j]));
|
||||||
}
|
|
||||||
vpx_idct8x8_64_add_c(coeff, dst, 8);
|
vpx_idct8x8_64_add_c(coeff, dst, 8);
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j) {
|
||||||
const int diff = dst[j] - src[j];
|
const int diff = dst[j] - src[j];
|
||||||
const int error = diff * diff;
|
const int error = diff * diff;
|
||||||
EXPECT_GE(1, error) << "Error: 8x8 FDCT/IDCT has error " << error
|
EXPECT_GE(1, error)
|
||||||
|
<< "Error: 8x8 FDCT/IDCT has error " << error
|
||||||
<< " at index " << j;
|
<< " at index " << j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
#include "./vpx_config.h"
|
||||||
#include "./vp8_rtcd.h"
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "test/buffer.h"
|
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
@@ -22,156 +20,101 @@ typedef void (*IdctFunc)(int16_t *input, unsigned char *pred_ptr,
|
|||||||
int pred_stride, unsigned char *dst_ptr,
|
int pred_stride, unsigned char *dst_ptr,
|
||||||
int dst_stride);
|
int dst_stride);
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using libvpx_test::Buffer;
|
|
||||||
|
|
||||||
class IDCTTest : public ::testing::TestWithParam<IdctFunc> {
|
class IDCTTest : public ::testing::TestWithParam<IdctFunc> {
|
||||||
protected:
|
protected:
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
|
int i;
|
||||||
|
|
||||||
UUT = GetParam();
|
UUT = GetParam();
|
||||||
|
memset(input, 0, sizeof(input));
|
||||||
input = new Buffer<int16_t>(4, 4, 0);
|
/* Set up guard blocks */
|
||||||
ASSERT_TRUE(input != NULL);
|
for (i = 0; i < 256; i++) output[i] = ((i & 0xF) < 4 && (i < 64)) ? 0 : -1;
|
||||||
ASSERT_TRUE(input->Init());
|
|
||||||
predict = new Buffer<uint8_t>(4, 4, 3);
|
|
||||||
ASSERT_TRUE(predict != NULL);
|
|
||||||
ASSERT_TRUE(predict->Init());
|
|
||||||
output = new Buffer<uint8_t>(4, 4, 3);
|
|
||||||
ASSERT_TRUE(output != NULL);
|
|
||||||
ASSERT_TRUE(output->Init());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() {
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
delete input;
|
|
||||||
delete predict;
|
|
||||||
delete output;
|
|
||||||
libvpx_test::ClearSystemState();
|
|
||||||
}
|
|
||||||
|
|
||||||
IdctFunc UUT;
|
IdctFunc UUT;
|
||||||
Buffer<int16_t> *input;
|
int16_t input[16];
|
||||||
Buffer<uint8_t> *predict;
|
unsigned char output[256];
|
||||||
Buffer<uint8_t> *output;
|
unsigned char predict[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TEST_P(IDCTTest, TestGuardBlocks) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
if ((i & 0xF) < 4 && i < 64)
|
||||||
|
EXPECT_EQ(0, output[i]) << i;
|
||||||
|
else
|
||||||
|
EXPECT_EQ(255, output[i]);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(IDCTTest, TestAllZeros) {
|
TEST_P(IDCTTest, TestAllZeros) {
|
||||||
// When the input is '0' the output will be '0'.
|
int i;
|
||||||
input->Set(0);
|
|
||||||
predict->Set(0);
|
|
||||||
output->Set(0);
|
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
||||||
predict->stride(), output->TopLeftPixel(),
|
|
||||||
output->stride()));
|
|
||||||
|
|
||||||
ASSERT_TRUE(input->CheckValues(0));
|
for (i = 0; i < 256; i++)
|
||||||
ASSERT_TRUE(input->CheckPadding());
|
if ((i & 0xF) < 4 && i < 64)
|
||||||
ASSERT_TRUE(output->CheckValues(0));
|
EXPECT_EQ(0, output[i]) << "i==" << i;
|
||||||
ASSERT_TRUE(output->CheckPadding());
|
else
|
||||||
|
EXPECT_EQ(255, output[i]) << "i==" << i;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(IDCTTest, TestAllOnes) {
|
TEST_P(IDCTTest, TestAllOnes) {
|
||||||
input->Set(0);
|
int i;
|
||||||
// When the first element is '4' it will fill the output buffer with '1'.
|
|
||||||
input->TopLeftPixel()[0] = 4;
|
|
||||||
predict->Set(0);
|
|
||||||
output->Set(0);
|
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
input[0] = 4;
|
||||||
predict->stride(), output->TopLeftPixel(),
|
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
||||||
output->stride()));
|
|
||||||
|
|
||||||
ASSERT_TRUE(output->CheckValues(1));
|
for (i = 0; i < 256; i++)
|
||||||
ASSERT_TRUE(output->CheckPadding());
|
if ((i & 0xF) < 4 && i < 64)
|
||||||
|
EXPECT_EQ(1, output[i]) << "i==" << i;
|
||||||
|
else
|
||||||
|
EXPECT_EQ(255, output[i]) << "i==" << i;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(IDCTTest, TestAddOne) {
|
TEST_P(IDCTTest, TestAddOne) {
|
||||||
// Set the transform output to '1' and make sure it gets added to the
|
int i;
|
||||||
// prediction buffer.
|
|
||||||
input->Set(0);
|
|
||||||
input->TopLeftPixel()[0] = 4;
|
|
||||||
output->Set(0);
|
|
||||||
|
|
||||||
uint8_t *pred = predict->TopLeftPixel();
|
for (i = 0; i < 256; i++) predict[i] = i;
|
||||||
for (int y = 0; y < 4; ++y) {
|
input[0] = 4;
|
||||||
for (int x = 0; x < 4; ++x) {
|
ASM_REGISTER_STATE_CHECK(UUT(input, predict, 16, output, 16));
|
||||||
pred[y * predict->stride() + x] = y * 4 + x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
for (i = 0; i < 256; i++)
|
||||||
predict->stride(), output->TopLeftPixel(),
|
if ((i & 0xF) < 4 && i < 64)
|
||||||
output->stride()));
|
EXPECT_EQ(i + 1, output[i]) << "i==" << i;
|
||||||
|
else
|
||||||
uint8_t const *out = output->TopLeftPixel();
|
EXPECT_EQ(255, output[i]) << "i==" << i;
|
||||||
for (int y = 0; y < 4; ++y) {
|
|
||||||
for (int x = 0; x < 4; ++x) {
|
|
||||||
EXPECT_EQ(1 + y * 4 + x, out[y * output->stride() + x]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HasFailure()) {
|
|
||||||
output->DumpBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT_TRUE(output->CheckPadding());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(IDCTTest, TestWithData) {
|
TEST_P(IDCTTest, TestWithData) {
|
||||||
// Test a single known input.
|
int i;
|
||||||
predict->Set(0);
|
|
||||||
|
|
||||||
int16_t *in = input->TopLeftPixel();
|
for (i = 0; i < 16; i++) input[i] = i;
|
||||||
for (int y = 0; y < 4; ++y) {
|
|
||||||
for (int x = 0; x < 4; ++x) {
|
|
||||||
in[y * input->stride() + x] = y * 4 + x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
||||||
predict->stride(), output->TopLeftPixel(),
|
|
||||||
output->stride()));
|
|
||||||
|
|
||||||
uint8_t *out = output->TopLeftPixel();
|
for (i = 0; i < 256; i++)
|
||||||
for (int y = 0; y < 4; ++y) {
|
if ((i & 0xF) > 3 || i > 63)
|
||||||
for (int x = 0; x < 4; ++x) {
|
EXPECT_EQ(255, output[i]) << "i==" << i;
|
||||||
switch (y * 4 + x) {
|
else if (i == 0)
|
||||||
case 0: EXPECT_EQ(11, out[y * output->stride() + x]); break;
|
EXPECT_EQ(11, output[i]) << "i==" << i;
|
||||||
case 2:
|
else if (i == 34)
|
||||||
case 5:
|
EXPECT_EQ(1, output[i]) << "i==" << i;
|
||||||
case 8: EXPECT_EQ(3, out[y * output->stride() + x]); break;
|
else if (i == 2 || i == 17 || i == 32)
|
||||||
case 10: EXPECT_EQ(1, out[y * output->stride() + x]); break;
|
EXPECT_EQ(3, output[i]) << "i==" << i;
|
||||||
default: EXPECT_EQ(0, out[y * output->stride() + x]);
|
else
|
||||||
}
|
EXPECT_EQ(0, output[i]) << "i==" << i;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HasFailure()) {
|
|
||||||
output->DumpBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT_TRUE(output->CheckPadding());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(C, IDCTTest, ::testing::Values(vp8_short_idct4x4llm_c));
|
INSTANTIATE_TEST_CASE_P(C, IDCTTest, ::testing::Values(vp8_short_idct4x4llm_c));
|
||||||
|
|
||||||
#if HAVE_NEON
|
|
||||||
INSTANTIATE_TEST_CASE_P(NEON, IDCTTest,
|
|
||||||
::testing::Values(vp8_short_idct4x4llm_neon));
|
|
||||||
#endif // HAVE_NEON
|
|
||||||
|
|
||||||
#if HAVE_MMX
|
#if HAVE_MMX
|
||||||
INSTANTIATE_TEST_CASE_P(MMX, IDCTTest,
|
INSTANTIATE_TEST_CASE_P(MMX, IDCTTest,
|
||||||
::testing::Values(vp8_short_idct4x4llm_mmx));
|
::testing::Values(vp8_short_idct4x4llm_mmx));
|
||||||
#endif // HAVE_MMX
|
#endif
|
||||||
|
|
||||||
#if HAVE_MSA
|
#if HAVE_MSA
|
||||||
INSTANTIATE_TEST_CASE_P(MSA, IDCTTest,
|
INSTANTIATE_TEST_CASE_P(MSA, IDCTTest,
|
||||||
::testing::Values(vp8_short_idct4x4llm_msa));
|
::testing::Values(vp8_short_idct4x4llm_msa));
|
||||||
#endif // HAVE_MSA
|
#endif
|
||||||
|
|
||||||
#if HAVE_MMI
|
|
||||||
INSTANTIATE_TEST_CASE_P(MMI, IDCTTest,
|
|
||||||
::testing::Values(vp8_short_idct4x4llm_mmi));
|
|
||||||
#endif // HAVE_MMI
|
|
||||||
}
|
}
|
||||||
|
|||||||
212
test/intrapred_test.cc
Normal file
212
test/intrapred_test.cc
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "./vpx_config.h"
|
||||||
|
#include "./vpx_dsp_rtcd.h"
|
||||||
|
#include "test/acm_random.h"
|
||||||
|
#include "test/clear_system_state.h"
|
||||||
|
#include "test/register_state_check.h"
|
||||||
|
#include "test/util.h"
|
||||||
|
#include "vp10/common/blockd.h"
|
||||||
|
#include "vp10/common/pred_common.h"
|
||||||
|
#include "vpx_mem/vpx_mem.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
|
const int count_test_block = 100000;
|
||||||
|
|
||||||
|
typedef void (*IntraPred)(uint16_t* dst, ptrdiff_t stride,
|
||||||
|
const uint16_t* above, const uint16_t* left,
|
||||||
|
int bps);
|
||||||
|
|
||||||
|
struct IntraPredFunc {
|
||||||
|
IntraPredFunc(IntraPred pred = NULL, IntraPred ref = NULL,
|
||||||
|
int block_size_value = 0, int bit_depth_value = 0)
|
||||||
|
: pred_fn(pred), ref_fn(ref),
|
||||||
|
block_size(block_size_value), bit_depth(bit_depth_value) {}
|
||||||
|
|
||||||
|
IntraPred pred_fn;
|
||||||
|
IntraPred ref_fn;
|
||||||
|
int block_size;
|
||||||
|
int bit_depth;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VP9IntraPredTest : public ::testing::TestWithParam<IntraPredFunc> {
|
||||||
|
public:
|
||||||
|
void RunTest(uint16_t* left_col, uint16_t* above_data,
|
||||||
|
uint16_t* dst, uint16_t* ref_dst) {
|
||||||
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
|
const int block_size = params_.block_size;
|
||||||
|
above_row_ = above_data + 16;
|
||||||
|
left_col_ = left_col;
|
||||||
|
dst_ = dst;
|
||||||
|
ref_dst_ = ref_dst;
|
||||||
|
int error_count = 0;
|
||||||
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
|
// Fill edges with random data, try first with saturated values.
|
||||||
|
for (int x = -1; x <= block_size * 2; x++) {
|
||||||
|
if (i == 0) {
|
||||||
|
above_row_[x] = mask_;
|
||||||
|
} else {
|
||||||
|
above_row_[x] = rnd.Rand16() & mask_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int y = 0; y < block_size; y++) {
|
||||||
|
if (i == 0) {
|
||||||
|
left_col_[y] = mask_;
|
||||||
|
} else {
|
||||||
|
left_col_[y] = rnd.Rand16() & mask_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Predict();
|
||||||
|
CheckPrediction(i, &error_count);
|
||||||
|
}
|
||||||
|
ASSERT_EQ(0, error_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void SetUp() {
|
||||||
|
params_ = GetParam();
|
||||||
|
stride_ = params_.block_size * 3;
|
||||||
|
mask_ = (1 << params_.bit_depth) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Predict() {
|
||||||
|
const int bit_depth = params_.bit_depth;
|
||||||
|
params_.ref_fn(ref_dst_, stride_, above_row_, left_col_, bit_depth);
|
||||||
|
ASM_REGISTER_STATE_CHECK(params_.pred_fn(dst_, stride_,
|
||||||
|
above_row_, left_col_, bit_depth));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckPrediction(int test_case_number, int *error_count) const {
|
||||||
|
// For each pixel ensure that the calculated value is the same as reference.
|
||||||
|
const int block_size = params_.block_size;
|
||||||
|
for (int y = 0; y < block_size; y++) {
|
||||||
|
for (int x = 0; x < block_size; x++) {
|
||||||
|
*error_count += ref_dst_[x + y * stride_] != dst_[x + y * stride_];
|
||||||
|
if (*error_count == 1) {
|
||||||
|
ASSERT_EQ(ref_dst_[x + y * stride_], dst_[x + y * stride_])
|
||||||
|
<< " Failed on Test Case Number "<< test_case_number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t *above_row_;
|
||||||
|
uint16_t *left_col_;
|
||||||
|
uint16_t *dst_;
|
||||||
|
uint16_t *ref_dst_;
|
||||||
|
ptrdiff_t stride_;
|
||||||
|
int mask_;
|
||||||
|
|
||||||
|
IntraPredFunc params_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(VP9IntraPredTest, IntraPredTests) {
|
||||||
|
// max block size is 32
|
||||||
|
DECLARE_ALIGNED(16, uint16_t, left_col[2*32]);
|
||||||
|
DECLARE_ALIGNED(16, uint16_t, above_data[2*32+32]);
|
||||||
|
DECLARE_ALIGNED(16, uint16_t, dst[3 * 32 * 32]);
|
||||||
|
DECLARE_ALIGNED(16, uint16_t, ref_dst[3 * 32 * 32]);
|
||||||
|
RunTest(left_col, above_data, dst, ref_dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_SSE2
|
||||||
|
#if CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
INSTANTIATE_TEST_CASE_P(SSE2_TO_C_8, VP9IntraPredTest,
|
||||||
|
::testing::Values(
|
||||||
|
IntraPredFunc(&vpx_highbd_dc_predictor_32x32_sse2,
|
||||||
|
&vpx_highbd_dc_predictor_32x32_c, 32, 8),
|
||||||
|
IntraPredFunc(&vpx_highbd_tm_predictor_16x16_sse2,
|
||||||
|
&vpx_highbd_tm_predictor_16x16_c, 16, 8),
|
||||||
|
IntraPredFunc(&vpx_highbd_tm_predictor_32x32_sse2,
|
||||||
|
&vpx_highbd_tm_predictor_32x32_c, 32, 8),
|
||||||
|
IntraPredFunc(&vpx_highbd_dc_predictor_4x4_sse2,
|
||||||
|
&vpx_highbd_dc_predictor_4x4_c, 4, 8),
|
||||||
|
IntraPredFunc(&vpx_highbd_dc_predictor_8x8_sse2,
|
||||||
|
&vpx_highbd_dc_predictor_8x8_c, 8, 8),
|
||||||
|
IntraPredFunc(&vpx_highbd_dc_predictor_16x16_sse2,
|
||||||
|
&vpx_highbd_dc_predictor_16x16_c, 16, 8),
|
||||||
|
IntraPredFunc(&vpx_highbd_v_predictor_4x4_sse2,
|
||||||
|
&vpx_highbd_v_predictor_4x4_c, 4, 8),
|
||||||
|
IntraPredFunc(&vpx_highbd_v_predictor_8x8_sse2,
|
||||||
|
&vpx_highbd_v_predictor_8x8_c, 8, 8),
|
||||||
|
IntraPredFunc(&vpx_highbd_v_predictor_16x16_sse2,
|
||||||
|
&vpx_highbd_v_predictor_16x16_c, 16, 8),
|
||||||
|
IntraPredFunc(&vpx_highbd_v_predictor_32x32_sse2,
|
||||||
|
&vpx_highbd_v_predictor_32x32_c, 32, 8),
|
||||||
|
IntraPredFunc(&vpx_highbd_tm_predictor_4x4_sse2,
|
||||||
|
&vpx_highbd_tm_predictor_4x4_c, 4, 8),
|
||||||
|
IntraPredFunc(&vpx_highbd_tm_predictor_8x8_sse2,
|
||||||
|
&vpx_highbd_tm_predictor_8x8_c, 8, 8)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(SSE2_TO_C_10, VP9IntraPredTest,
|
||||||
|
::testing::Values(
|
||||||
|
IntraPredFunc(&vpx_highbd_dc_predictor_32x32_sse2,
|
||||||
|
&vpx_highbd_dc_predictor_32x32_c, 32, 10),
|
||||||
|
IntraPredFunc(&vpx_highbd_tm_predictor_16x16_sse2,
|
||||||
|
&vpx_highbd_tm_predictor_16x16_c, 16, 10),
|
||||||
|
IntraPredFunc(&vpx_highbd_tm_predictor_32x32_sse2,
|
||||||
|
&vpx_highbd_tm_predictor_32x32_c, 32, 10),
|
||||||
|
IntraPredFunc(&vpx_highbd_dc_predictor_4x4_sse2,
|
||||||
|
&vpx_highbd_dc_predictor_4x4_c, 4, 10),
|
||||||
|
IntraPredFunc(&vpx_highbd_dc_predictor_8x8_sse2,
|
||||||
|
&vpx_highbd_dc_predictor_8x8_c, 8, 10),
|
||||||
|
IntraPredFunc(&vpx_highbd_dc_predictor_16x16_sse2,
|
||||||
|
&vpx_highbd_dc_predictor_16x16_c, 16, 10),
|
||||||
|
IntraPredFunc(&vpx_highbd_v_predictor_4x4_sse2,
|
||||||
|
&vpx_highbd_v_predictor_4x4_c, 4, 10),
|
||||||
|
IntraPredFunc(&vpx_highbd_v_predictor_8x8_sse2,
|
||||||
|
&vpx_highbd_v_predictor_8x8_c, 8, 10),
|
||||||
|
IntraPredFunc(&vpx_highbd_v_predictor_16x16_sse2,
|
||||||
|
&vpx_highbd_v_predictor_16x16_c, 16, 10),
|
||||||
|
IntraPredFunc(&vpx_highbd_v_predictor_32x32_sse2,
|
||||||
|
&vpx_highbd_v_predictor_32x32_c, 32, 10),
|
||||||
|
IntraPredFunc(&vpx_highbd_tm_predictor_4x4_sse2,
|
||||||
|
&vpx_highbd_tm_predictor_4x4_c, 4, 10),
|
||||||
|
IntraPredFunc(&vpx_highbd_tm_predictor_8x8_sse2,
|
||||||
|
&vpx_highbd_tm_predictor_8x8_c, 8, 10)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(SSE2_TO_C_12, VP9IntraPredTest,
|
||||||
|
::testing::Values(
|
||||||
|
IntraPredFunc(&vpx_highbd_dc_predictor_32x32_sse2,
|
||||||
|
&vpx_highbd_dc_predictor_32x32_c, 32, 12),
|
||||||
|
IntraPredFunc(&vpx_highbd_tm_predictor_16x16_sse2,
|
||||||
|
&vpx_highbd_tm_predictor_16x16_c, 16, 12),
|
||||||
|
IntraPredFunc(&vpx_highbd_tm_predictor_32x32_sse2,
|
||||||
|
&vpx_highbd_tm_predictor_32x32_c, 32, 12),
|
||||||
|
IntraPredFunc(&vpx_highbd_dc_predictor_4x4_sse2,
|
||||||
|
&vpx_highbd_dc_predictor_4x4_c, 4, 12),
|
||||||
|
IntraPredFunc(&vpx_highbd_dc_predictor_8x8_sse2,
|
||||||
|
&vpx_highbd_dc_predictor_8x8_c, 8, 12),
|
||||||
|
IntraPredFunc(&vpx_highbd_dc_predictor_16x16_sse2,
|
||||||
|
&vpx_highbd_dc_predictor_16x16_c, 16, 12),
|
||||||
|
IntraPredFunc(&vpx_highbd_v_predictor_4x4_sse2,
|
||||||
|
&vpx_highbd_v_predictor_4x4_c, 4, 12),
|
||||||
|
IntraPredFunc(&vpx_highbd_v_predictor_8x8_sse2,
|
||||||
|
&vpx_highbd_v_predictor_8x8_c, 8, 12),
|
||||||
|
IntraPredFunc(&vpx_highbd_v_predictor_16x16_sse2,
|
||||||
|
&vpx_highbd_v_predictor_16x16_c, 16, 12),
|
||||||
|
IntraPredFunc(&vpx_highbd_v_predictor_32x32_sse2,
|
||||||
|
&vpx_highbd_v_predictor_32x32_c, 32, 12),
|
||||||
|
IntraPredFunc(&vpx_highbd_tm_predictor_4x4_sse2,
|
||||||
|
&vpx_highbd_tm_predictor_4x4_c, 4, 12),
|
||||||
|
IntraPredFunc(&vpx_highbd_tm_predictor_8x8_sse2,
|
||||||
|
&vpx_highbd_tm_predictor_8x8_c, 8, 12)));
|
||||||
|
|
||||||
|
#endif // CONFIG_VPX_HIGHBITDEPTH
|
||||||
|
#endif // HAVE_SSE2
|
||||||
|
} // namespace
|
||||||
@@ -1,214 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "test/codec_factory.h"
|
|
||||||
#include "test/decode_test_driver.h"
|
|
||||||
#include "test/ivf_video_source.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
#if CONFIG_WEBM_IO
|
|
||||||
#include "test/webm_video_source.h"
|
|
||||||
#endif
|
|
||||||
#include "vpx_mem/vpx_mem.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
struct DecodeParam {
|
|
||||||
int threads;
|
|
||||||
const char *filename;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &os, const DecodeParam &dp) {
|
|
||||||
return os << "threads: " << dp.threads << " file: " << dp.filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InvalidFileTest : public ::libvpx_test::DecoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWithParam<DecodeParam> {
|
|
||||||
protected:
|
|
||||||
InvalidFileTest() : DecoderTest(GET_PARAM(0)), res_file_(NULL) {}
|
|
||||||
|
|
||||||
virtual ~InvalidFileTest() {
|
|
||||||
if (res_file_ != NULL) fclose(res_file_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenResFile(const std::string &res_file_name_) {
|
|
||||||
res_file_ = libvpx_test::OpenTestDataFile(res_file_name_);
|
|
||||||
ASSERT_TRUE(res_file_ != NULL)
|
|
||||||
<< "Result file open failed. Filename: " << res_file_name_;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool HandleDecodeResult(
|
|
||||||
const vpx_codec_err_t res_dec,
|
|
||||||
const libvpx_test::CompressedVideoSource &video,
|
|
||||||
libvpx_test::Decoder *decoder) {
|
|
||||||
EXPECT_TRUE(res_file_ != NULL);
|
|
||||||
int expected_res_dec;
|
|
||||||
|
|
||||||
// Read integer result.
|
|
||||||
const int res = fscanf(res_file_, "%d", &expected_res_dec);
|
|
||||||
EXPECT_NE(res, EOF) << "Read result data failed";
|
|
||||||
|
|
||||||
// Check results match.
|
|
||||||
const DecodeParam input = GET_PARAM(1);
|
|
||||||
if (input.threads > 1) {
|
|
||||||
// The serial decode check is too strict for tile-threaded decoding as
|
|
||||||
// there is no guarantee on the decode order nor which specific error
|
|
||||||
// will take precedence. Currently a tile-level error is not forwarded so
|
|
||||||
// the frame will simply be marked corrupt.
|
|
||||||
EXPECT_TRUE(res_dec == expected_res_dec ||
|
|
||||||
res_dec == VPX_CODEC_CORRUPT_FRAME)
|
|
||||||
<< "Results don't match: frame number = " << video.frame_number()
|
|
||||||
<< ". (" << decoder->DecodeError()
|
|
||||||
<< "). Expected: " << expected_res_dec << " or "
|
|
||||||
<< VPX_CODEC_CORRUPT_FRAME;
|
|
||||||
} else {
|
|
||||||
EXPECT_EQ(expected_res_dec, res_dec)
|
|
||||||
<< "Results don't match: frame number = " << video.frame_number()
|
|
||||||
<< ". (" << decoder->DecodeError() << ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
return !HasFailure();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunTest() {
|
|
||||||
const DecodeParam input = GET_PARAM(1);
|
|
||||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
|
||||||
cfg.threads = input.threads;
|
|
||||||
const std::string filename = input.filename;
|
|
||||||
|
|
||||||
// Open compressed video file.
|
|
||||||
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
|
||||||
if (filename.substr(filename.length() - 3, 3) == "ivf") {
|
|
||||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
|
||||||
} else if (filename.substr(filename.length() - 4, 4) == "webm") {
|
|
||||||
#if CONFIG_WEBM_IO
|
|
||||||
video.reset(new libvpx_test::WebMVideoSource(filename));
|
|
||||||
#else
|
|
||||||
fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
|
|
||||||
filename.c_str());
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
ASSERT_TRUE(video.get() != NULL);
|
|
||||||
video->Init();
|
|
||||||
|
|
||||||
// Construct result file name. The file holds a list of expected integer
|
|
||||||
// results, one for each decoded frame. Any result that doesn't match
|
|
||||||
// the files list will cause a test failure.
|
|
||||||
const std::string res_filename = filename + ".res";
|
|
||||||
OpenResFile(res_filename);
|
|
||||||
|
|
||||||
// Decode frame, and check the md5 matching.
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get(), cfg));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
FILE *res_file_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(InvalidFileTest, ReturnCode) { RunTest(); }
|
|
||||||
|
|
||||||
#if CONFIG_VP8_DECODER
|
|
||||||
const DecodeParam kVP8InvalidFileTests[] = {
|
|
||||||
{ 1, "invalid-bug-1443.ivf" },
|
|
||||||
};
|
|
||||||
|
|
||||||
VP8_INSTANTIATE_TEST_CASE(InvalidFileTest,
|
|
||||||
::testing::ValuesIn(kVP8InvalidFileTests));
|
|
||||||
#endif // CONFIG_VP8_DECODER
|
|
||||||
|
|
||||||
#if CONFIG_VP9_DECODER
|
|
||||||
const DecodeParam kVP9InvalidFileTests[] = {
|
|
||||||
{ 1, "invalid-vp90-02-v2.webm" },
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
{ 1, "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf" },
|
|
||||||
{ 1,
|
|
||||||
"invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-."
|
|
||||||
"ivf" },
|
|
||||||
#endif
|
|
||||||
{ 1, "invalid-vp90-03-v3.webm" },
|
|
||||||
{ 1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf" },
|
|
||||||
{ 1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf" },
|
|
||||||
// This file will cause a large allocation which is expected to fail in 32-bit
|
|
||||||
// environments. Test x86 for coverage purposes as the allocation failure will
|
|
||||||
// be in platform agnostic code.
|
|
||||||
#if ARCH_X86
|
|
||||||
{ 1, "invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf" },
|
|
||||||
#endif
|
|
||||||
{ 1, "invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf" },
|
|
||||||
{ 1, "invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf" },
|
|
||||||
{ 1, "invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf" },
|
|
||||||
{ 1, "invalid-vp91-2-mixedrefcsp-444to420.ivf" },
|
|
||||||
{ 1, "invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf" },
|
|
||||||
{ 1, "invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf" },
|
|
||||||
{ 1, "invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf" },
|
|
||||||
{ 1,
|
|
||||||
"invalid-vp90-2-10-show-existing-frame.webm.ivf.s180315_r01-05_b6-.ivf" },
|
|
||||||
{ 1, "invalid-crbug-667044.webm" },
|
|
||||||
};
|
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(InvalidFileTest,
|
|
||||||
::testing::ValuesIn(kVP9InvalidFileTests));
|
|
||||||
#endif // CONFIG_VP9_DECODER
|
|
||||||
|
|
||||||
// This class will include test vectors that are expected to fail
|
|
||||||
// peek. However they are still expected to have no fatal failures.
|
|
||||||
class InvalidFileInvalidPeekTest : public InvalidFileTest {
|
|
||||||
protected:
|
|
||||||
InvalidFileInvalidPeekTest() : InvalidFileTest() {}
|
|
||||||
virtual void HandlePeekResult(libvpx_test::Decoder *const /*decoder*/,
|
|
||||||
libvpx_test::CompressedVideoSource * /*video*/,
|
|
||||||
const vpx_codec_err_t /*res_peek*/) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(InvalidFileInvalidPeekTest, ReturnCode) { RunTest(); }
|
|
||||||
|
|
||||||
#if CONFIG_VP8_DECODER
|
|
||||||
const DecodeParam kVP8InvalidPeekTests[] = {
|
|
||||||
{ 1, "invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf" },
|
|
||||||
};
|
|
||||||
|
|
||||||
VP8_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest,
|
|
||||||
::testing::ValuesIn(kVP8InvalidPeekTests));
|
|
||||||
#endif // CONFIG_VP8_DECODER
|
|
||||||
|
|
||||||
#if CONFIG_VP9_DECODER
|
|
||||||
const DecodeParam kVP9InvalidFileInvalidPeekTests[] = {
|
|
||||||
{ 1, "invalid-vp90-01-v3.webm" },
|
|
||||||
};
|
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest,
|
|
||||||
::testing::ValuesIn(kVP9InvalidFileInvalidPeekTests));
|
|
||||||
|
|
||||||
const DecodeParam kMultiThreadedVP9InvalidFileTests[] = {
|
|
||||||
{ 4, "invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm" },
|
|
||||||
{ 4,
|
|
||||||
"invalid-"
|
|
||||||
"vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf" },
|
|
||||||
{ 4,
|
|
||||||
"invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf" },
|
|
||||||
{ 2, "invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf" },
|
|
||||||
{ 4, "invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf" },
|
|
||||||
{ 2, "invalid-crbug-629481.webm" },
|
|
||||||
};
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
VP9MultiThreaded, InvalidFileTest,
|
|
||||||
::testing::Combine(
|
|
||||||
::testing::Values(
|
|
||||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
|
|
||||||
::testing::ValuesIn(kMultiThreadedVP9InvalidFileTests)));
|
|
||||||
#endif // CONFIG_VP9_DECODER
|
|
||||||
} // namespace
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user