Compare commits
608 Commits
master
...
zhoulongyu
Author | SHA1 | Date | |
---|---|---|---|
3a9264b31d | |||
c5436c077f | |||
![]() |
fd9395dd89 | ||
![]() |
e56c3d5bc5 | ||
![]() |
038fffac22 | ||
![]() |
dae04243be | ||
![]() |
0c139866d2 | ||
![]() |
bae3a21d7b | ||
![]() |
573ce84da7 | ||
![]() |
fefc76b1cd | ||
![]() |
64f7777c5e | ||
![]() |
33824829cd | ||
![]() |
d556078a7e | ||
![]() |
0e6ab49076 | ||
![]() |
7cfcd56f87 | ||
![]() |
281a1aa60f | ||
![]() |
03303797fe | ||
![]() |
2bfc255a57 | ||
![]() |
a56fc1dcdc | ||
![]() |
cb5c52bae8 | ||
![]() |
732caa9440 | ||
![]() |
280afb79c5 | ||
![]() |
6a107520f7 | ||
![]() |
11203a87c5 | ||
![]() |
1a06ed0494 | ||
![]() |
f5366a4bcf | ||
![]() |
5fccf8f991 | ||
![]() |
918210d695 | ||
![]() |
35f8b4093b | ||
![]() |
1b7ff22112 | ||
![]() |
a4bd40a847 | ||
![]() |
7093b61fe9 | ||
![]() |
3c3b934bd1 | ||
![]() |
4278452de1 | ||
![]() |
59f6b7ec8b | ||
![]() |
a476c4fc82 | ||
![]() |
3a2a01efd7 | ||
![]() |
2a8655a76a | ||
![]() |
f1f1c7bfa3 | ||
![]() |
49d3a9e7c7 | ||
![]() |
547888643f | ||
![]() |
0f60695c14 | ||
![]() |
3a4538a82c | ||
![]() |
93cb0f8573 | ||
![]() |
dd0f1b0895 | ||
![]() |
0b49e1a2ec | ||
![]() |
d15663c9f7 | ||
![]() |
196a325497 | ||
![]() |
ce3e00d4d7 | ||
![]() |
a9f698bf8b | ||
![]() |
9ccc38c9e7 | ||
![]() |
cf7ac85f1f | ||
![]() |
93c02056b5 | ||
![]() |
59dd2bda6a | ||
![]() |
7d6164959e | ||
![]() |
da5aa894c7 | ||
![]() |
19aa5e1599 | ||
![]() |
4c6cf898cf | ||
![]() |
e038e2a9ff | ||
![]() |
42e1e62756 | ||
![]() |
7bf75e7754 | ||
![]() |
bc61427deb | ||
![]() |
7282ce3a08 | ||
![]() |
8a34d9e8be | ||
![]() |
c88dbe1ecf | ||
![]() |
b748ccbfb2 | ||
![]() |
90f0ebd438 | ||
![]() |
beecc6659f | ||
![]() |
63946512aa | ||
![]() |
eb71b5c880 | ||
![]() |
7ba189be9b | ||
![]() |
dc8a17cc3e | ||
![]() |
479248eb01 | ||
![]() |
03993fde2e | ||
![]() |
c434f4fbe4 | ||
![]() |
04243196d3 | ||
![]() |
18d5145467 | ||
![]() |
7db59beae6 | ||
![]() |
ec8cccc0f9 | ||
![]() |
ff4eb8bf07 | ||
![]() |
e7ce303ec3 | ||
![]() |
0ceb3acc2b | ||
![]() |
e82adfc4d5 | ||
![]() |
b530437393 | ||
![]() |
abc8fb252a | ||
![]() |
00571f6917 | ||
![]() |
f10edc656b | ||
![]() |
8e07140ca3 | ||
![]() |
4706bfa7dd | ||
![]() |
3644358597 | ||
![]() |
cf16b8bca8 | ||
![]() |
fa360ed2ac | ||
![]() |
0d2153b307 | ||
![]() |
068faf817f | ||
![]() |
87cfe980ca | ||
![]() |
e4e1e0545a | ||
![]() |
e992b29e2d | ||
![]() |
8270c6ced2 | ||
![]() |
f60ab92134 | ||
![]() |
fe0b956592 | ||
![]() |
86a441f877 | ||
![]() |
430af82b88 | ||
![]() |
4edb207b1d | ||
![]() |
f6173a8786 | ||
![]() |
08bfc6e9ba | ||
![]() |
680996176b | ||
![]() |
f94c292ff4 | ||
![]() |
ace3384905 | ||
![]() |
79a55c01f6 | ||
![]() |
9c851492d3 | ||
![]() |
a17cc5e307 | ||
![]() |
0d8e8ce3c1 | ||
![]() |
0c84cdce63 | ||
![]() |
c033475732 | ||
![]() |
b7674539dd | ||
![]() |
519af895ef | ||
![]() |
39ab107f7d | ||
![]() |
f51e928d87 | ||
![]() |
d5ed510a20 | ||
![]() |
7659ad8cd2 | ||
![]() |
ac578c063a | ||
![]() |
21a97dc6f2 | ||
![]() |
3b532d55c3 | ||
![]() |
be27463b15 | ||
![]() |
5e4354cde0 | ||
![]() |
e7c4b2d41f | ||
![]() |
6bb8c76751 | ||
![]() |
7619c74561 | ||
![]() |
9a5c945797 | ||
![]() |
5fa12e5021 | ||
![]() |
cc98adc8fe | ||
![]() |
d9dfbd5f9a | ||
![]() |
7cd64c0f03 | ||
![]() |
57895ef440 | ||
![]() |
ab3fd3cc3d | ||
![]() |
1783d9849f | ||
![]() |
88707966a6 | ||
![]() |
67d5e2014f | ||
![]() |
833b69a823 | ||
![]() |
509142a0fa | ||
![]() |
3f2bd025b4 | ||
![]() |
cb0948f81f | ||
![]() |
f3824bd71b | ||
![]() |
977d5e78c1 | ||
![]() |
094329fcd6 | ||
![]() |
b9f67a16b2 | ||
![]() |
0a7bf55c3e | ||
![]() |
7e6b8d4605 | ||
![]() |
2c9a659d4c | ||
![]() |
113275600c | ||
![]() |
a20ed62c08 | ||
![]() |
af6f25397f | ||
![]() |
3ad19bbbb8 | ||
![]() |
7493f4c22f | ||
![]() |
fc21bc1cb2 | ||
![]() |
3edb1a82bb | ||
![]() |
4d2d330389 | ||
![]() |
3218f07a34 | ||
![]() |
bbf674035a | ||
![]() |
e821de5832 | ||
![]() |
ff763d81ce | ||
![]() |
a2159d9951 | ||
![]() |
281c4dfe73 | ||
![]() |
a9b4eee4ea | ||
![]() |
31ac2138d5 | ||
![]() |
8f4665c372 | ||
![]() |
3df4cacf07 | ||
![]() |
7c9984033c | ||
![]() |
701942f6bc | ||
![]() |
5afefb6a81 | ||
![]() |
a2bf7b84e7 | ||
![]() |
c4910dc80b | ||
![]() |
cbfc5081a2 | ||
![]() |
1441b28c15 | ||
![]() |
d85e4ed790 | ||
![]() |
f0c02cef1a | ||
![]() |
bcad96ab84 | ||
![]() |
16e98073d8 | ||
![]() |
a0070c5747 | ||
![]() |
2d9e3711b1 | ||
![]() |
093fbbb1ed | ||
![]() |
68d1dd58ca | ||
![]() |
c3e5571e37 | ||
![]() |
079f480076 | ||
![]() |
be566f10db | ||
![]() |
353aa7d63e | ||
![]() |
70042cc449 | ||
![]() |
5089d4415f | ||
![]() |
ce1cbbb9b4 | ||
![]() |
d674a839a1 | ||
![]() |
eec9fb49a2 | ||
![]() |
6bd70cc0e5 | ||
![]() |
6c8bb74be1 | ||
![]() |
4834d682d4 | ||
![]() |
023bf9bbea | ||
![]() |
21e6d4fd09 | ||
![]() |
8511e2947a | ||
![]() |
69e69ba86e | ||
![]() |
9c371dfe19 | ||
![]() |
8c5eee015d | ||
![]() |
956337f1ce | ||
![]() |
59fccf3ad1 | ||
![]() |
7c261bdaad | ||
![]() |
cf45a7d007 | ||
![]() |
88ea6411b9 | ||
![]() |
21432a5719 | ||
![]() |
5c95effe7c | ||
![]() |
19247f0646 | ||
![]() |
b1edd64314 | ||
![]() |
5711ce11eb | ||
![]() |
4b88568d15 | ||
![]() |
25bc0699ca | ||
![]() |
e3cfcabd3d | ||
![]() |
b5599a42af | ||
![]() |
1bb7420eb8 | ||
![]() |
8f89a12e5e | ||
![]() |
1b6e073d5d | ||
![]() |
dadebb3f64 | ||
![]() |
844ecd7e8b | ||
![]() |
53662789e1 | ||
![]() |
467e998479 | ||
![]() |
9567a6cd66 | ||
![]() |
7c1a8ddd74 | ||
![]() |
95aa8c86c9 | ||
![]() |
16b86dbe0e | ||
![]() |
27ad9ac682 | ||
![]() |
b8751307c9 | ||
![]() |
a879da6532 | ||
![]() |
0eb06e4213 | ||
![]() |
744bf103c9 | ||
![]() |
e05547f0a4 | ||
![]() |
784d3a9b1d | ||
![]() |
de3c1df7ac | ||
![]() |
fad78bd4a4 | ||
![]() |
7df38a8e2a | ||
![]() |
d6841b4b19 | ||
![]() |
e2eacfd48e | ||
![]() |
049521bad1 | ||
![]() |
073087411b | ||
![]() |
96ed848470 | ||
![]() |
a1e14a3f27 | ||
![]() |
2fd4cb0714 | ||
![]() |
2f475aa6bb | ||
![]() |
5ef7097863 | ||
![]() |
f57790010c | ||
![]() |
05ee22d556 | ||
![]() |
5057623540 | ||
![]() |
15303359d6 | ||
![]() |
081397e560 | ||
![]() |
949f29fbd7 | ||
![]() |
70a8d15021 | ||
![]() |
ec7634f22d | ||
![]() |
385884baec | ||
![]() |
ae9e0a67c1 | ||
![]() |
9bf22417f5 | ||
![]() |
328d81ac3e | ||
![]() |
b305614fda | ||
![]() |
b299854b90 | ||
![]() |
980cd6a4ff | ||
![]() |
1732cb9c63 | ||
![]() |
f0d002b8b9 | ||
![]() |
3b7f7ba326 | ||
![]() |
935c24770a | ||
![]() |
df85a88d62 | ||
![]() |
075d82be2a | ||
![]() |
e82f4f43f8 | ||
![]() |
275c1aa59d | ||
![]() |
bc5290047b | ||
![]() |
75bd13b7a6 | ||
![]() |
f0062b96c2 | ||
![]() |
7abf2d7a76 | ||
![]() |
d11518383a | ||
![]() |
80ba0a816f | ||
![]() |
61df3be654 | ||
![]() |
6387490182 | ||
![]() |
cc493b6c3d | ||
![]() |
15c42d8f1a | ||
![]() |
3809e8c4b7 | ||
![]() |
1faa9b566c | ||
![]() |
e2d6455746 | ||
![]() |
2d495b6f00 | ||
![]() |
f5043e8efe | ||
![]() |
70749f4612 | ||
![]() |
9802e42e67 | ||
![]() |
d71ea78114 | ||
![]() |
5aacc2a245 | ||
![]() |
f02d2b4a6d | ||
![]() |
6610558788 | ||
![]() |
d8f7e2c076 | ||
![]() |
e7659d197d | ||
![]() |
40b5a835f8 | ||
![]() |
ef0a94eb55 | ||
![]() |
2fe56a23ae | ||
![]() |
a1d76b0339 | ||
![]() |
9351b0611e | ||
![]() |
ed9771b5b5 | ||
![]() |
8cf8280a2c | ||
![]() |
e830334096 | ||
![]() |
aaadf977f8 | ||
![]() |
656c5b7d39 | ||
![]() |
1f364ab7f0 | ||
![]() |
97ff5431d2 | ||
![]() |
4e2de1ef55 | ||
![]() |
8aaf9b4074 | ||
![]() |
1e42c00ae2 | ||
![]() |
79a29db217 | ||
![]() |
2f89bc8681 | ||
![]() |
3ba9078ef9 | ||
![]() |
bb0180882c | ||
![]() |
2f6678c7eb | ||
![]() |
7fd6c72864 | ||
![]() |
7ebd2e3aa7 | ||
![]() |
a7fc63285c | ||
![]() |
6f6e8eb7cd | ||
![]() |
a2f8103fa5 | ||
![]() |
0b976c4619 | ||
![]() |
b8cd52e849 | ||
![]() |
e5a2d7cfd9 | ||
![]() |
13cb172160 | ||
![]() |
ea21b9df91 | ||
![]() |
6830104fcd | ||
![]() |
73a7ca3787 | ||
![]() |
cbb9e2a5d2 | ||
![]() |
2956868344 | ||
![]() |
1c41198dc1 | ||
![]() |
7ecc3a58b3 | ||
![]() |
f85f6fb4f5 | ||
![]() |
936fc127da | ||
![]() |
7d706cc822 | ||
![]() |
ddb61c4b91 | ||
![]() |
4780a46e8a | ||
![]() |
9a10d9e16a | ||
![]() |
053d2dbda3 | ||
![]() |
7f5847cbdb | ||
![]() |
d4f57d78cd | ||
![]() |
6021af6acd | ||
![]() |
f0c1e95f8f | ||
![]() |
daa873e32a | ||
![]() |
03101fd6a5 | ||
![]() |
d361b7a3a9 | ||
![]() |
ca522ccd78 | ||
![]() |
a45b623aff | ||
![]() |
5f3aa045b3 | ||
![]() |
6482585855 | ||
![]() |
5ba829db67 | ||
![]() |
b68ef7834a | ||
![]() |
ff53e3d2c6 | ||
![]() |
00912847ed | ||
![]() |
f48be0f224 | ||
![]() |
b11ebd8e4c | ||
![]() |
a2fda414d0 | ||
![]() |
7eda62875b | ||
![]() |
3cf1a1d8bd | ||
![]() |
18c0123ea9 | ||
![]() |
d7a472277d | ||
![]() |
9564f60597 | ||
![]() |
44a74ac4aa | ||
![]() |
2d0bf0ff64 | ||
![]() |
b28b337f36 | ||
![]() |
2b4130595b | ||
![]() |
78967a59df | ||
![]() |
af9dc3c906 | ||
![]() |
7233841a4a | ||
![]() |
b4d5fa020d | ||
![]() |
d3dca44f91 | ||
![]() |
82b6cf4663 | ||
![]() |
d42b38c5dc | ||
![]() |
1b22cd3f63 | ||
![]() |
402baf38f9 | ||
![]() |
8ddb9d917d | ||
![]() |
50be3bf21b | ||
![]() |
0c4f039918 | ||
![]() |
c01a4f636f | ||
![]() |
ffce54a373 | ||
![]() |
7b3691bd36 | ||
![]() |
6d23741b77 | ||
![]() |
a73b84039a | ||
![]() |
3fef82c7d4 | ||
![]() |
d69554af64 | ||
![]() |
2db19bc9b6 | ||
![]() |
dd0a7304f5 | ||
![]() |
202e502b90 | ||
![]() |
3964a430ec | ||
![]() |
1046ac2eff | ||
![]() |
67c79c2c6e | ||
![]() |
08031ed4fa | ||
![]() |
480d5ee9c7 | ||
![]() |
8c1a1045a3 | ||
![]() |
359eec1914 | ||
![]() |
64ad852f91 | ||
![]() |
c679ced96c | ||
![]() |
8b85c03e8d | ||
![]() |
a224a5a387 | ||
![]() |
24de40d2f6 | ||
![]() |
8a66f07266 | ||
![]() |
818aea1417 | ||
![]() |
fdbe733bc7 | ||
![]() |
d05a8757cf | ||
![]() |
a02fcf958b | ||
![]() |
4efd610707 | ||
![]() |
9fe836864e | ||
![]() |
0de968d42e | ||
![]() |
10921b1b57 | ||
![]() |
73236bba8f | ||
![]() |
5989d9df2d | ||
![]() |
48a5c6f4ba | ||
![]() |
1ada288d3f | ||
![]() |
dcdf20106e | ||
![]() |
c81a611f66 | ||
![]() |
ce3da311a6 | ||
![]() |
d19ccfc67b | ||
![]() |
1f862db3de | ||
![]() |
677544e458 | ||
![]() |
a574550a8e | ||
![]() |
b190fcead7 | ||
![]() |
67993b88ca | ||
![]() |
9ca156dcb3 | ||
![]() |
9933fb45b0 | ||
![]() |
f1747df345 | ||
![]() |
8a79fe352c | ||
![]() |
c1ed1cadb5 | ||
![]() |
74a9705d97 | ||
![]() |
cb2c073c3d | ||
![]() |
4627d47f50 | ||
![]() |
e3dc20d7a4 | ||
![]() |
524fb9db30 | ||
![]() |
859a4b8ce2 | ||
![]() |
63bcd37b66 | ||
![]() |
2feccc7d36 | ||
![]() |
4a904e004e | ||
![]() |
40310496e9 | ||
69b327bfdc | |||
![]() |
92a62a1db6 | ||
![]() |
f56defee42 | ||
![]() |
e781fbf37d | ||
![]() |
988d2a03e5 | ||
![]() |
0529077864 | ||
![]() |
f6ee22a2d1 | ||
![]() |
c91ddb6456 | ||
![]() |
3229dddf3a | ||
![]() |
7706998056 | ||
![]() |
9cfaaf4c48 | ||
![]() |
9e912b240f | ||
![]() |
a2c4fa60ec | ||
![]() |
c1a5ad44a9 | ||
![]() |
6e11dc58f6 | ||
![]() |
06a0edbfd0 | ||
![]() |
328b12abc9 | ||
![]() |
c6ab66d3ec | ||
![]() |
b99d2c9461 | ||
![]() |
9b12014f76 | ||
![]() |
20c2ad46aa | ||
1b11f55fa4 | |||
ca56f16a20 | |||
532598fbaa | |||
![]() |
9a6ca65cde | ||
![]() |
a471e12ff1 | ||
![]() |
e4fb89ba1a | ||
![]() |
b3b4e80931 | ||
![]() |
20be0d73ed | ||
![]() |
690f71e131 | ||
![]() |
30aac0ee1b | ||
![]() |
fcc0a7b1ec | ||
d47aff4e47 | |||
985ae0edef | |||
c25e185c93 | |||
ae20412ee7 | |||
18c4877ec9 | |||
7a0bfe7a4d | |||
4853e5c038 | |||
85ab73ddc0 | |||
336e1863d3 | |||
e6b0040e7b | |||
![]() |
9f07183680 | ||
![]() |
3ab940b725 | ||
9aebd2158b | |||
d06477d707 | |||
730c38b2c1 | |||
d44154773f | |||
c5691b1b95 | |||
b94f6ac956 | |||
1d214080ce | |||
efa068fea2 | |||
c629d6b63f | |||
584e202b07 | |||
91ae7dbc67 | |||
9e78b4e163 | |||
![]() |
8cacfdf5d2 | ||
![]() |
5d06d53ace | ||
![]() |
0f67e707a3 | ||
![]() |
ddcb6d2581 | ||
![]() |
1757fc8513 | ||
![]() |
fc424e4044 | ||
![]() |
7f5e9f7d24 | ||
69c3de538f | |||
bd3f58213f | |||
803b2c89aa | |||
![]() |
e1244d5e5e | ||
![]() |
004fc6d72a | ||
![]() |
81ce17838d | ||
![]() |
f989e8fe2d | ||
![]() |
65e7988002 | ||
![]() |
a0666c1311 | ||
![]() |
fb43de75ed | ||
![]() |
99004e8a6f | ||
![]() |
a9cc7abe6b | ||
![]() |
dd1cfab956 | ||
![]() |
3f6502c332 | ||
![]() |
94054f4337 | ||
![]() |
7cbda9b450 | ||
![]() |
e0c4744eda | ||
![]() |
8e626bc451 | ||
![]() |
0ad532315c | ||
![]() |
339466aecf | ||
![]() |
17205de4c6 | ||
![]() |
518e108644 | ||
![]() |
1bf1a4ddca | ||
![]() |
2af2c45e7a | ||
![]() |
882af7f6b0 | ||
![]() |
f008337684 | ||
![]() |
9fe9bba31a | ||
![]() |
893319acb6 | ||
![]() |
56f399dd15 | ||
![]() |
7867d78b42 | ||
![]() |
a9adff1a60 | ||
![]() |
aaa3fb036d | ||
![]() |
c345c87297 | ||
![]() |
1cbcbe5e69 | ||
![]() |
8ff62492e0 | ||
![]() |
169ac7a0dd | ||
![]() |
c459515071 | ||
![]() |
dd9b3df32d | ||
![]() |
6c5379565b | ||
![]() |
8c9d0d89cb | ||
![]() |
2d74fe6e19 | ||
![]() |
3dc608da22 | ||
![]() |
fac9558524 | ||
![]() |
0d8a07bbcc | ||
![]() |
690522256a | ||
![]() |
cdccef76a7 | ||
![]() |
461fa73bf4 | ||
![]() |
2eca81afe6 | ||
![]() |
a60d476935 | ||
![]() |
0e8ecc75d4 | ||
![]() |
915dfd2338 | ||
![]() |
7a3d819229 | ||
![]() |
395f30e076 | ||
![]() |
523a6b8b99 | ||
![]() |
01e9deaa77 | ||
![]() |
1930349f6e | ||
![]() |
155edbee92 | ||
![]() |
08d451c882 | ||
![]() |
9fc61803f1 | ||
![]() |
a80dbac00e | ||
![]() |
3daf05fa02 | ||
![]() |
3c52037560 | ||
![]() |
076a6da052 | ||
![]() |
9f9abd7130 | ||
![]() |
cee11f19a7 | ||
![]() |
a4ed1ba3a0 | ||
![]() |
8451121750 | ||
![]() |
b3cc7ef2a7 | ||
![]() |
f8ccddc10c | ||
aa9d39368d | |||
![]() |
ac50191203 | ||
![]() |
99c2431a4c | ||
![]() |
d6e56ae4b5 | ||
![]() |
56fb165029 | ||
![]() |
a80a8f7cee | ||
![]() |
850d757423 | ||
![]() |
2d3074454f | ||
![]() |
0ee6dd1e5e | ||
![]() |
0be56111db | ||
![]() |
b9e2e92df9 | ||
![]() |
df3ddf6cd5 | ||
![]() |
45a7b9e764 | ||
![]() |
e14eeb7ad8 | ||
![]() |
8fece6d8c6 | ||
![]() |
080c1f6c64 | ||
![]() |
e45d061399 | ||
![]() |
85ac294cb8 | ||
![]() |
0524c5554f | ||
![]() |
9099831066 | ||
![]() |
36dbb97146 | ||
![]() |
29ef5292c0 | ||
![]() |
6d886d26eb | ||
![]() |
5b3152355e | ||
![]() |
82816c4ead | ||
![]() |
0190074367 | ||
![]() |
c2830a4e87 | ||
![]() |
feba1578fa | ||
![]() |
548b2acfa6 | ||
![]() |
7a693216d8 | ||
![]() |
5a50d4af18 | ||
![]() |
7a0490b689 | ||
![]() |
aa635a3001 | ||
![]() |
b7739f7602 | ||
![]() |
75068605ce | ||
![]() |
a91c04d9d4 | ||
![]() |
f0f16f67bd | ||
c82df95b02 | |||
e3f407af27 | |||
![]() |
8f64f21161 | ||
83b1ed75b6 | |||
e09b0f1049 | |||
8b4e5d1f57 | |||
50af2a429a | |||
5d34ede653 |
|
@ -102,10 +102,8 @@ if ("${CLANG_TIDY_SUPPORT}" MATCHES "true")
|
|||
message(FATAL_ERROR "You set support clang-tidy, but clang-tidy not found.
|
||||
Check path ${LLVM_PATH}/build/bin, weather clang-tidy exist.
|
||||
How to install tools?
|
||||
See ${IPC_SDK_PATH}/doc/clang-tidy_user_guide.md
|
||||
How to disable clang-tidy tool?
|
||||
Modify: set(CLANG_TIDY_SUPPORT \"false\")
|
||||
See:${IPC_SDK_PATH}/builde/global_config.cmake")
|
||||
Execute : make compile_llvm (in the project root directory)
|
||||
Or see ${CMAKE_SOURCE_DIR_IPCSDK}/doc/clang-tidy_user_guide.md")
|
||||
endif()
|
||||
endif()
|
||||
# find the clang-format tools
|
||||
|
@ -164,6 +162,9 @@ set(MAIN_SRC_FILE "" CACHE STRING INTERNAL)
|
|||
unset(MAIN_LINK_LIB CACHE)
|
||||
set(MAIN_LINK_LIB "" CACHE STRING INTERNAL)
|
||||
|
||||
unset(EXTERNAL_LIBS_PATH CACHE)
|
||||
set(EXTERNAL_LIBS_PATH "" CACHE STRING INTERNAL)
|
||||
|
||||
# Config message for test code.
|
||||
unset(TEST_LINK_LIB CACHE)
|
||||
set(TEST_LINK_LIB "" CACHE STRING INTERNAL)
|
||||
|
|
32
README.md
32
README.md
|
@ -9,11 +9,33 @@
|
|||
* SDK工程所有开发文档均使用markdown语法编写,需要使用markdown语法解析器进行解析,方便阅读,如:Typora;开发工程师建议使用vscode安装markdownlint插件进行阅读;
|
||||
* SDK工程所有文档描述路径时,"//"双斜杠表示工程根目录;
|
||||
|
||||
## 1.2. 编译
|
||||
## 1.2. 开发环境准备
|
||||
|
||||
  工程的开发,需要预安装一些开发工具。例如:cmake的特定版本,llvm工具等。
|
||||
|
||||
### 1.2.1. cmake安装
|
||||
|
||||
  cmake是一个跨平台的安装(编译)工具,它是由Kitware公司开发的一个开源软件,可以用来配置、构建、编译一个工程。
|
||||
|
||||
```code
|
||||
# 项目根目录执行:
|
||||
$ make install_cmake
|
||||
```
|
||||
|
||||
### 1.2.2. llvm工具安装
|
||||
|
||||
  LLVM是一个编译器工具链,包含clang编译器、llvm核心库等。此处只用了clang-tidy和clang-format工具,一个负责编码规范,一个负责代码格式化。
|
||||
|
||||
```code
|
||||
# 项目根目录执行:
|
||||
$ make compile_llvm
|
||||
```
|
||||
|
||||
## 1.3. 编译
|
||||
|
||||
  架构设计上支持去平台编译和运行,本仓库源码可仿真运行在ubuntu系统。
|
||||
|
||||
### 1.2.1. Ubuntu系统
|
||||
### 1.3.1. Ubuntu系统
|
||||
|
||||
在项目根目录下执行命令:
|
||||
|
||||
|
@ -24,7 +46,7 @@ cd cmake-shell/ // 在中间文件目录进行编译,把所有中间文件
|
|||
make // 编译全部输出构建文件
|
||||
```
|
||||
|
||||
### 1.2.2. 交叉编译
|
||||
### 1.3.2. 交叉编译
|
||||
|
||||
参考:
|
||||
|
||||
|
@ -37,9 +59,9 @@ make // 编译全部输出构建文件
|
|||
|
||||
  交叉编译请参考基于IPC SDK作为子仓库的工程配置,此处忽略。
|
||||
|
||||
### 1.2.3. 小技巧
|
||||
### 1.3.3. 小技巧
|
||||
|
||||
#### 1.2.3.1. 代码阅读辅助工具(基于vscode)
|
||||
#### 1.3.3.1. 代码阅读辅助工具(基于vscode)
|
||||
|
||||
  为了方便代码跳转阅读,除了安装基本的c++插件外,结合cmake构建工具生成的compile_commands.json文件可实现代码之间的精准跳转。
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ include_directories(
|
|||
link_directories(
|
||||
${LIBS_OUTPUT_PATH}
|
||||
${EXTERNAL_LIBS_OUTPUT_PATH}
|
||||
${EXTERNAL_LIBS_PATH}
|
||||
)
|
||||
|
||||
aux_source_directory(. SRC_FILES)
|
||||
|
@ -30,7 +31,6 @@ if(${TEST_COVERAGE} MATCHES "true")
|
|||
target_link_libraries(${TARGET_NAME} gcov)
|
||||
endif()
|
||||
|
||||
if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true")
|
||||
add_custom_target(
|
||||
HuntingCamera_code_check
|
||||
COMMAND ${CLANG_TIDY_EXE}
|
||||
|
@ -43,12 +43,6 @@ add_custom_target(
|
|||
-p ${PLATFORM_PATH}/cmake-shell
|
||||
WORKING_DIRECTORY ${APPLICATION_SOURCE_PATH}/HuntingCamera
|
||||
)
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
PRE_BUILD
|
||||
COMMAND make HuntingCamera_code_check
|
||||
WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/
|
||||
)
|
||||
file(GLOB_RECURSE HEADER_FILES *.h)
|
||||
add_custom_target(
|
||||
HuntingCamera_code_format
|
||||
|
@ -57,6 +51,7 @@ add_custom_target(
|
|||
-i ${SRC_FILES} ${MAIN_SRC_FILE_THIS} ${HEADER_FILES}
|
||||
WORKING_DIRECTORY ${APPLICATION_SOURCE_PATH}/HuntingCamera
|
||||
)
|
||||
if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true")
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
PRE_BUILD
|
||||
|
|
|
@ -20,6 +20,7 @@ include_directories(
|
|||
${MIDDLEWARE_SOURCE_PATH}/McuAskBase/include
|
||||
${MIDDLEWARE_SOURCE_PATH}/HuntingUpgrade/include
|
||||
${MIDDLEWARE_SOURCE_PATH}/DeviceManager/include
|
||||
${MIDDLEWARE_SOURCE_PATH}/IpcConfig/include
|
||||
)
|
||||
#do not rely on any other library
|
||||
#link_directories(
|
||||
|
@ -30,9 +31,8 @@ aux_source_directory(./src SRC_FILES)
|
|||
set(TARGET_NAME MissionManager)
|
||||
add_library(${TARGET_NAME} STATIC ${SRC_FILES})
|
||||
|
||||
target_link_libraries(${TARGET_NAME} McuAskBase StateMachine MediaManager StorageManager DeviceManager HuntingUpgrade KeyControl LedControl StatusCode Log)
|
||||
target_link_libraries(${TARGET_NAME} McuAskBase StateMachine MediaManager StorageManager DeviceManager HuntingUpgrade KeyControl LedControl IpcConfig StatusCode Log)
|
||||
|
||||
if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true")
|
||||
add_custom_target(
|
||||
MissionManager_code_check
|
||||
COMMAND ${CLANG_TIDY_EXE}
|
||||
|
@ -44,12 +44,6 @@ add_custom_target(
|
|||
-p ${PLATFORM_PATH}/cmake-shell
|
||||
WORKING_DIRECTORY ${APPLICATION_SOURCE_PATH}/MissionManager
|
||||
)
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
PRE_BUILD
|
||||
COMMAND make MissionManager_code_check
|
||||
WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/
|
||||
)
|
||||
file(GLOB_RECURSE HEADER_FILES *.h)
|
||||
add_custom_target(
|
||||
MissionManager_code_format
|
||||
|
@ -58,6 +52,7 @@ add_custom_target(
|
|||
-i ${SRC_FILES} ${HEADER_FILES}
|
||||
WORKING_DIRECTORY ${APPLICATION_SOURCE_PATH}/MissionManager
|
||||
)
|
||||
if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true")
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
PRE_BUILD
|
||||
|
|
|
@ -21,8 +21,9 @@ stateDiagram-v2
|
|||
[*] --> TopState
|
||||
TopState --> PowerOff
|
||||
TopState --> MSDCState
|
||||
TopState --> DeviceAbnormal
|
||||
TopState --> MissionState
|
||||
TopState --> DeviceAbnormal
|
||||
TopState --> FormattingSDCard
|
||||
MissionState --> 空闲
|
||||
MissionState --> 存储管理
|
||||
存储管理 --> EMMC
|
||||
|
@ -79,4 +80,10 @@ end
|
|||
|
||||
## 1.4. MCU监视器
|
||||
|
||||
  MCU监视器必须由其中一个状态继承,只有状态机运行之后才能处理串口命令。
|
||||
  MCU监视器必须由其中一个状态继承,只有状态机运行之后才能处理串口命令。
|
||||
|
||||
## 1.5. 测试启动模式(TestMissionState)
|
||||
|
||||
  面向用户开放的测试模式。
|
||||
|
||||
1. 此状态下,先按下format按键不放,再按下reset按键不放可以关闭喂狗功能;
|
||||
|
|
|
@ -13,8 +13,16 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "AppMonitor.h"
|
||||
#include "IAppManager.h"
|
||||
#include "IFilesManager.h"
|
||||
#include "ILog.h"
|
||||
#include "IStorageManager.h"
|
||||
#include "MediaTask.h"
|
||||
#include "StatusCode.h"
|
||||
#include <vector>
|
||||
AppMonitor::AppMonitor() : mMicStatus(SwitchStatus::END)
|
||||
{
|
||||
}
|
||||
StatusCode AppMonitor::GetProductInfo(AppGetProductInfo ¶m)
|
||||
{
|
||||
LogInfo("AppMonitor::GetProductInfo.\n");
|
||||
|
@ -65,7 +73,7 @@ StatusCode AppMonitor::GetBatteryInfo(AppGetBatteryInfo ¶m)
|
|||
}
|
||||
StatusCode AppMonitor::GetParamValue(AppParamValue ¶m)
|
||||
{
|
||||
param.mMicStatus = SwitchStatus::ON;
|
||||
param.mMicStatus = mMicStatus;
|
||||
param.mRec = SwitchStatus::OFF;
|
||||
return CreateStatusCode(STATUS_CODE_OK);
|
||||
}
|
||||
|
@ -94,36 +102,59 @@ StatusCode AppMonitor::GetStorageInfo(std::vector<AppGetStorageInfo> ¶m)
|
|||
}
|
||||
StatusCode AppMonitor::GetStorageFileList(const AppGetFileInfo &fileInfo, std::vector<AppGetFileList> ¶m)
|
||||
{
|
||||
if (StorageFileEvent::LOOP == fileInfo.mEvent) {
|
||||
std::vector<SyncFileInfo> info;
|
||||
if (StorageFileEvent::ALL == fileInfo.mEvent) {
|
||||
IFilesManager::GetInstance()->GetAllFiles(info);
|
||||
}
|
||||
else {
|
||||
std::vector<FileCreateType> types;
|
||||
if (StorageFileEvent::LOOP == fileInfo.mEvent) {
|
||||
types.push_back(FileCreateType::TIMED);
|
||||
types.push_back(FileCreateType::MANUAL_TEST);
|
||||
types.push_back(FileCreateType::MANUAL_PHONE);
|
||||
types.push_back(FileCreateType::TIMED);
|
||||
}
|
||||
if (StorageFileEvent::EMR == fileInfo.mEvent) {
|
||||
types.push_back(FileCreateType::PIR);
|
||||
}
|
||||
if (StorageFileEvent::EVENT == fileInfo.mEvent) {
|
||||
types.push_back(FileCreateType::MANUAL_TEST);
|
||||
types.push_back(FileCreateType::MANUAL_PHONE);
|
||||
}
|
||||
if (StorageFileEvent::PARK == fileInfo.mEvent) {
|
||||
types.push_back(FileCreateType::TIMED);
|
||||
}
|
||||
IFilesManager::GetInstance()->GetFiles(types, info);
|
||||
}
|
||||
const std::string webServerDocumentRoot = IAppManager::GetInstance()->GetFilesSavingRootPath();
|
||||
LogInfo("GetStorageFileList: file size = %d, event = %s.\n",
|
||||
info.size(),
|
||||
IAppManager::GetInstance()->StorageFileEventToString(fileInfo.mEvent));
|
||||
for (auto &oneFileInfo : info) {
|
||||
AppGetFileList file;
|
||||
file.mCreateTime_s = 123456789;
|
||||
file.mDuration = 182;
|
||||
file.mName = "/DCIM/2024/01/15/20240115140207-20240115140509.mp4";
|
||||
file.mSize = 1024 * 182;
|
||||
file.mCreateTime_s = oneFileInfo.mCreateTime_s;
|
||||
file.mDuration = oneFileInfo.mFileDuration;
|
||||
file.mName = RemovePrefix(oneFileInfo.mFileName, webServerDocumentRoot);
|
||||
file.mSize = oneFileInfo.mFileSize;
|
||||
file.mType = StorageFileType::VIDEO;
|
||||
param.push_back(file);
|
||||
AppGetFileList file2;
|
||||
file2.mCreateTime_s = 123456789;
|
||||
file2.mDuration = 0;
|
||||
file2.mName = "/34a396526922a33e97906920dbfef2a5.jpg";
|
||||
file2.mSize = 1024;
|
||||
file2.mType = StorageFileType::PICTURE;
|
||||
param.push_back(file2);
|
||||
}
|
||||
return CreateStatusCode(STATUS_CODE_OK);
|
||||
}
|
||||
StatusCode AppMonitor::SetDateTime(const AppSetDateTime ¶m)
|
||||
{
|
||||
//
|
||||
return CreateStatusCode(STATUS_CODE_OK);
|
||||
}
|
||||
StatusCode AppMonitor::SetTimeZone(const unsigned int &zone)
|
||||
{
|
||||
//
|
||||
return CreateStatusCode(STATUS_CODE_OK);
|
||||
}
|
||||
StatusCode AppMonitor::SetParamValue(const AppSetParamValue ¶m)
|
||||
{
|
||||
LogInfo("SetParamValue: param = %s.\n", param.mName.c_str());
|
||||
if (param.mName == "mic") {
|
||||
mMicStatus = static_cast<SwitchStatus>(param.mValue);
|
||||
}
|
||||
return CreateStatusCode(STATUS_CODE_OK);
|
||||
}
|
||||
StatusCode AppMonitor::EnterRecorder(void)
|
||||
|
@ -136,12 +167,14 @@ StatusCode AppMonitor::AppPlayback(const PlayBackEvent &event)
|
|||
}
|
||||
StatusCode AppMonitor::UploadFile(AppUploadFile ¶m)
|
||||
{
|
||||
//
|
||||
return CreateStatusCode(STATUS_CODE_OK);
|
||||
}
|
||||
StatusCode AppMonitor::GetThumbnail(AppGetThumbnail ¶m)
|
||||
{
|
||||
param.mThumbnail = "./34a396526922a33e97906920dbfef2a5.jpg";
|
||||
// param.mThumbnail = "./34a396526922a33e97906920dbfef2a5.jpg";
|
||||
const std::string webServerDocumentRoot = IAppManager::GetInstance()->GetFilesSavingRootPath();
|
||||
const std::string thumbnailFile = MediaTask::GetThumbnailNameByTargetName(param.mFile);
|
||||
param.mThumbnail = thumbnailFile;
|
||||
return CreateStatusCode(STATUS_CODE_OK);
|
||||
}
|
||||
SdCardStatus AppMonitor::SdCardStatusConvert(const StorageEvent &event)
|
||||
|
@ -156,4 +189,12 @@ SdCardStatus AppMonitor::SdCardStatusConvert(const StorageEvent &event)
|
|||
default:
|
||||
return SdCardStatus::END;
|
||||
}
|
||||
}
|
||||
std::string AppMonitor::RemovePrefix(const std::string &originalStr, const std::string &prefix)
|
||||
{
|
||||
if (originalStr.compare(0, prefix.length(), prefix) == 0) {
|
||||
return originalStr.substr(prefix.length());
|
||||
}
|
||||
LogWarning("Something wrong happened, prefix is %s.\n", prefix.c_str());
|
||||
return originalStr;
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
class AppMonitor : public VAppMonitor
|
||||
{
|
||||
public:
|
||||
AppMonitor() = default;
|
||||
AppMonitor();
|
||||
virtual ~AppMonitor() = default;
|
||||
StatusCode GetProductInfo(AppGetProductInfo ¶m) override;
|
||||
StatusCode GetDeviceAttr(AppGetDeviceAttr ¶m) override;
|
||||
|
@ -41,5 +41,9 @@ public:
|
|||
|
||||
private:
|
||||
SdCardStatus SdCardStatusConvert(const StorageEvent &event);
|
||||
std::string RemovePrefix(const std::string &originalStr, const std::string &prefix);
|
||||
|
||||
private:
|
||||
SwitchStatus mMicStatus; // TODO: improve delete.
|
||||
};
|
||||
#endif
|
|
@ -14,6 +14,13 @@
|
|||
*/
|
||||
#include "DataProcessing.h"
|
||||
#include "ILog.h"
|
||||
#include "IMissionManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "KeyControl.h"
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
const bool NOT_EXECUTED = false;
|
||||
const bool EXECUTED = true;
|
||||
key_event_data::key_event_data(const std::string &keyName, const KeyEvent &keyEvent, const unsigned int &holdTime)
|
||||
|
|
|
@ -24,13 +24,15 @@ using DataProcessingFunc = std::function<bool(VStateMachineData *)>;
|
|||
enum class InternalStateEvent
|
||||
{
|
||||
STORAGE_HANDLE_STATE_INIT = static_cast<int>(MissionEvent::END),
|
||||
SD_CARD_HANDLE_STATE_SD_STATUS_REPORTED,
|
||||
ANY_STATE_SD_STATUS_PERORIED,
|
||||
SD_CARD_HANDLE_STATE_SD_STATUS_REPORTED, ///< Only SdCardHandleState can process this message.
|
||||
ANY_STATE_SD_STATUS_PERORIED, ///< Use it to notify other statuses.
|
||||
CHECK_UPGRADE_FILE,
|
||||
MEDIA_REPORT_EVENT,
|
||||
MEDIA_REPORT_EVENT, ///< Media events proactively reported by the bottom layer.
|
||||
KEY_EVENT_HANDLE,
|
||||
RESET_KEY_MEDIA_TASK,
|
||||
FORMAT_KEY_FORMAT_SD_CARD,
|
||||
MEDIA_HANDLE_STATE_TASK_TIME_OUT,
|
||||
MEDIA_HANDLE_STATE_TASK_FINISHED,
|
||||
END
|
||||
};
|
||||
typedef struct key_event_data
|
||||
|
|
93
application/MissionManager/src/FormattingState.cpp
Normal file
93
application/MissionManager/src/FormattingState.cpp
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Fancy Code.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "FormattingState.h"
|
||||
#include "DataProcessing.h"
|
||||
#include "IFilesManager.h"
|
||||
#include "ILog.h"
|
||||
#include "IMissionManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "IStorageManager.h"
|
||||
#include "LedControl.h"
|
||||
#include "LedsHandle.h"
|
||||
#include "MissionStateMachine.h"
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
using std::placeholders::_1;
|
||||
FormattingState::FormattingState() : State("FormattingState"), mFormatting(false)
|
||||
{
|
||||
mEventHandle[InternalStateEvent::FORMAT_KEY_FORMAT_SD_CARD] =
|
||||
std::bind(&FormattingState::FormatKeyFormattingSDCardHandle, this, _1);
|
||||
mEventHandle[InternalStateEvent::SD_CARD_HANDLE_STATE_SD_STATUS_REPORTED] =
|
||||
std::bind(&FormattingState::ComfirmFormatResult, this, _1);
|
||||
}
|
||||
void FormattingState::GoInState()
|
||||
{
|
||||
LogInfo(" ========== FormattingState::GoInState.\n");
|
||||
}
|
||||
void FormattingState::GoOutState()
|
||||
{
|
||||
LogInfo(" ========== FormattingState::GoOutState.\n");
|
||||
if (mFormattingThread.joinable()) {
|
||||
mFormattingThread.join();
|
||||
}
|
||||
mFormatting = false;
|
||||
LedsHandle::DeleteAllLeds();
|
||||
}
|
||||
bool FormattingState::ExecuteStateMsg(VStateMachineData *msg)
|
||||
{
|
||||
return DataProcessing::EventHandle(msg);
|
||||
}
|
||||
void FormattingState::StateInit(void)
|
||||
{
|
||||
}
|
||||
void FormattingState::StateUnInit(void)
|
||||
{
|
||||
if (mFormattingThread.joinable()) {
|
||||
mFormattingThread.join();
|
||||
}
|
||||
}
|
||||
bool FormattingState::FormatKeyFormattingSDCardHandle(VStateMachineData *msg)
|
||||
{
|
||||
LogInfo("Now formatting SD card.\n");
|
||||
auto formatting = [](std::shared_ptr<FormattingState> impl) {
|
||||
impl->FormattingThread();
|
||||
};
|
||||
mFormatting = true;
|
||||
mFormattingThread = std::thread(formatting, shared_from_this());
|
||||
return EXECUTED;
|
||||
}
|
||||
bool FormattingState::ComfirmFormatResult(VStateMachineData *msg)
|
||||
{
|
||||
std::shared_ptr<MissionMessage> message = std::dynamic_pointer_cast<MissionMessage>(msg->GetMessageObj());
|
||||
std::shared_ptr<VMissionDataV2<StorageEvent>> data =
|
||||
std::dynamic_pointer_cast<VMissionDataV2<StorageEvent>>(message->mMissionData);
|
||||
LogInfo(" SdCardEventHandle event:%s.\n", IStorageManager::GetInstance()->PrintStringStorageEvent(data->mData));
|
||||
if (StorageEvent::SD_CARD_INSERT == data->mData) {
|
||||
LogInfo(" SD card inserted. Format sd card final finished.\n");
|
||||
// MissionStateMachine::GetInstance()->SwitchState(SystemState::IDLE_STATE);
|
||||
MissionStateMachine::GetInstance()->DelayMessage(msg);
|
||||
MissionStateMachine::GetInstance()->SwitchState(SystemState::SD_CARD_HANDLE_STATE);
|
||||
}
|
||||
return EXECUTED;
|
||||
}
|
||||
void FormattingState::FormattingThread(void)
|
||||
{
|
||||
LedsHandle::ControlDeviceStatusLed(DeviceStatus::FORMATTING, KEEP_ALIVE_FOREVER, BLINKING_FAST_MS);
|
||||
IFilesManager::GetInstance()->UnInit();
|
||||
IStorageManager::GetInstance()->FormatSDCardNow();
|
||||
// IFilesManager::GetInstance()->Init();
|
||||
// MissionStateMachine::GetInstance()->SwitchState(SystemState::IDLE_STATE);
|
||||
LogInfo("Formatting SD card done.\n");
|
||||
}
|
50
application/MissionManager/src/FormattingState.h
Normal file
50
application/MissionManager/src/FormattingState.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Fancy Code.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef FORMATTING_STATE_H
|
||||
#define FORMATTING_STATE_H
|
||||
#include "DataProcessing.h"
|
||||
#include "IFilesManager.h"
|
||||
#include "IMediaManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "IStorageManager.h"
|
||||
#include "LedsHandle.h"
|
||||
#include "VStateBase.h"
|
||||
#include <thread>
|
||||
class FormattingState : public State,
|
||||
public DataProcessing,
|
||||
public VStateBase,
|
||||
public LedsHandle,
|
||||
public std::enable_shared_from_this<FormattingState>
|
||||
{
|
||||
public:
|
||||
FormattingState();
|
||||
virtual ~FormattingState() = default;
|
||||
void GoInState() override;
|
||||
void GoOutState() override;
|
||||
bool ExecuteStateMsg(VStateMachineData *msg) override;
|
||||
|
||||
protected:
|
||||
void StateInit(void) override;
|
||||
void StateUnInit(void) override;
|
||||
bool FormatKeyFormattingSDCardHandle(VStateMachineData *msg);
|
||||
bool ComfirmFormatResult(VStateMachineData *msg);
|
||||
void FormattingThread(void);
|
||||
|
||||
private:
|
||||
bool mFormatting;
|
||||
std::thread mFormattingThread;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -14,6 +14,8 @@
|
|||
*/
|
||||
#include "IMissionManager.h"
|
||||
#include "ILog.h"
|
||||
#include "StatusCode.h"
|
||||
#include <memory>
|
||||
std::shared_ptr<IMissionManager> &IMissionManager::GetInstance(std::shared_ptr<IMissionManager> *impl)
|
||||
{
|
||||
static auto instance = std::make_shared<IMissionManager>();
|
||||
|
|
|
@ -13,15 +13,16 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "IdleState.h"
|
||||
#include "IFilesManager.h"
|
||||
#include "DataProcessing.h"
|
||||
#include "ILog.h"
|
||||
#include "IMediaManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "MissionStateMachine.h"
|
||||
#include <functional>
|
||||
IdleState::IdleState() : State("IdleState")
|
||||
{
|
||||
// mEventHandle[InternalStateEvent::MEDIA_REPORT_EVENT] = std::bind(&IdleState::MediaReportHandle, this, _1);
|
||||
// mEventHandle[InternalStateEvent::SD_CARD_HANDLE_STATE_SD_STATUS_REPORTED] =
|
||||
// std::bind(&IdleState::SdCardEventHandle, this, _1);
|
||||
mEventHandle[InternalStateEvent::RESET_KEY_MEDIA_TASK] = std::bind(&IdleState::ResetKeyMediaTaskHandle, this, _1);
|
||||
mEventHandle[InternalStateEvent::FORMAT_KEY_FORMAT_SD_CARD] =
|
||||
std::bind(&IdleState::FormatKeyFormattingSDCardHandle, this, _1);
|
||||
}
|
||||
void IdleState::GoInState()
|
||||
{
|
||||
|
@ -34,4 +35,16 @@ void IdleState::GoOutState()
|
|||
bool IdleState::ExecuteStateMsg(VStateMachineData *msg)
|
||||
{
|
||||
return DataProcessing::EventHandle(msg);
|
||||
}
|
||||
bool IdleState::ResetKeyMediaTaskHandle(VStateMachineData *msg)
|
||||
{
|
||||
MissionStateMachine::GetInstance()->DelayMessage(msg);
|
||||
MissionStateMachine::GetInstance()->SwitchState(SystemState::STORAGE_HANDLE_STATE);
|
||||
return EXECUTED;
|
||||
}
|
||||
bool IdleState::FormatKeyFormattingSDCardHandle(VStateMachineData *msg)
|
||||
{
|
||||
MissionStateMachine::GetInstance()->DelayMessage(msg);
|
||||
MissionStateMachine::GetInstance()->SwitchState(SystemState::STORAGE_HANDLE_STATE);
|
||||
return EXECUTED;
|
||||
}
|
|
@ -25,6 +25,10 @@ public:
|
|||
void GoOutState() override;
|
||||
bool ExecuteStateMsg(VStateMachineData *msg) override;
|
||||
|
||||
private:
|
||||
bool ResetKeyMediaTaskHandle(VStateMachineData *msg);
|
||||
bool FormatKeyFormattingSDCardHandle(VStateMachineData *msg);
|
||||
|
||||
private:
|
||||
};
|
||||
#endif
|
|
@ -14,22 +14,59 @@
|
|||
*/
|
||||
#include "LedsHandle.h"
|
||||
#include "ILog.h"
|
||||
#include "LedControl.h"
|
||||
#include "SetLedState.h"
|
||||
LedsHandle::LedsHandle() : mDeviceStatusFlag(DeviceStatus::END)
|
||||
{
|
||||
}
|
||||
void LedsHandle::ControlDeviceStatusLed(const DeviceStatus &status, const long int &keepAliveTime,
|
||||
const unsigned int &blinkPeriod)
|
||||
{
|
||||
if (KEEP_ALIVE_FOREVER == keepAliveTime) {
|
||||
/**
|
||||
* @brief For a specific state instance, when controlling the same indicator light, if the permanently
|
||||
* maintained state changes, the original state needs to be overwritten.
|
||||
*/
|
||||
DeleteDeviceStatusLed();
|
||||
}
|
||||
switch (status) {
|
||||
case DeviceStatus::NORMAL:
|
||||
mDeviceStatus = SetLedState::ControlLed("device_status", LedState::GREEN, keepAliveTime, blinkPeriod);
|
||||
break;
|
||||
case DeviceStatus::FORMAT_KEY_HOLD_DOWN_TIPS:
|
||||
// if (DeviceStatus::FORMAT_KEY_HOLD_DOWN_TIPS == mDeviceStatusFlag) {
|
||||
// break;
|
||||
// }
|
||||
mDeviceStatus = SetLedState::ControlLed("device_status", LedState::RED, keepAliveTime, blinkPeriod);
|
||||
break;
|
||||
case DeviceStatus::FORMATTING:
|
||||
mDeviceStatus = SetLedState::ControlLed("device_status", LedState::RED, keepAliveTime, blinkPeriod);
|
||||
break;
|
||||
case DeviceStatus::SD_CARD_REMOVE:
|
||||
mDeviceStatus = SetLedState::ControlLed("device_status", LedState::GREEN, keepAliveTime, blinkPeriod);
|
||||
break;
|
||||
case DeviceStatus::SD_CARD_ABNORMAL:
|
||||
mDeviceStatus = SetLedState::ControlLed("device_status", LedState::RED, keepAliveTime, blinkPeriod);
|
||||
break;
|
||||
case DeviceStatus::TAKING_PICTURE_OR_VIDEO:
|
||||
mDeviceStatus = SetLedState::ControlLed("device_status", LedState::GREEN, keepAliveTime, blinkPeriod);
|
||||
break;
|
||||
case DeviceStatus::CLOSE_WATCHDOG:
|
||||
mDeviceStatus = SetLedState::ControlLed("device_status", LedState::RED, keepAliveTime, blinkPeriod);
|
||||
break;
|
||||
|
||||
default:
|
||||
LogWarning("unknow device status.\n");
|
||||
break;
|
||||
}
|
||||
mDeviceStatusFlag = status;
|
||||
}
|
||||
void inline LedsHandle::DeleteDeviceStatusLed(void)
|
||||
void LedsHandle::DeleteDeviceStatusLed(void)
|
||||
{
|
||||
mDeviceStatus->DeleteState();
|
||||
if (mDeviceStatus) {
|
||||
mDeviceStatus->DeleteState();
|
||||
mDeviceStatus.reset();
|
||||
}
|
||||
}
|
||||
void LedsHandle::DeleteAllLeds(void)
|
||||
{
|
||||
|
|
|
@ -19,12 +19,21 @@ enum class DeviceStatus
|
|||
{
|
||||
NORMAL = 0,
|
||||
TAKING_PICTURE_OR_VIDEO,
|
||||
FORMATTING, ///< Prompt the user that the formatting operation is being performed.
|
||||
FORMAT_KEY_HOLD_DOWN_TIPS, ///< Prompt the user that the format button has been pressed.
|
||||
SD_CARD_REMOVE,
|
||||
SD_CARD_INSERT,
|
||||
SD_CARD_ABNORMAL,
|
||||
CLOSE_WATCHDOG,
|
||||
END
|
||||
};
|
||||
/**
|
||||
* @brief LedsHandle-LED light control class, mainly used to inherit LED light control functions in different states.
|
||||
*/
|
||||
class LedsHandle
|
||||
{
|
||||
public:
|
||||
LedsHandle() = default;
|
||||
LedsHandle();
|
||||
virtual ~LedsHandle() = default;
|
||||
|
||||
protected:
|
||||
|
@ -41,6 +50,12 @@ protected:
|
|||
void DeleteAllLeds(void);
|
||||
|
||||
private:
|
||||
std::shared_ptr<SetLedState> mDeviceStatus;
|
||||
/**
|
||||
* @brief Definitions of various LED indicators.
|
||||
* NOTE: When indicator lights with different functions switch states, the previous light state should be cleared by
|
||||
* calling the DeleteState function.
|
||||
*/
|
||||
std::shared_ptr<SetLedState> mDeviceStatus; ///< Device status indicator.
|
||||
DeviceStatus mDeviceStatusFlag;
|
||||
};
|
||||
#endif
|
|
@ -15,6 +15,7 @@
|
|||
#include "McuMonitor.h"
|
||||
#include "ILog.h"
|
||||
#include "IMcuManager.h"
|
||||
#include <memory>
|
||||
void McuMonitor::Init(std::shared_ptr<VMcuMonitor> &monitor)
|
||||
{
|
||||
IMcuManager::GetInstance()->SetMcuMonitor(monitor);
|
||||
|
|
|
@ -13,14 +13,26 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "MediaHandleState.h"
|
||||
#include "DataProcessing.h"
|
||||
#include "IFilesManager.h"
|
||||
#include "ILog.h"
|
||||
#include "IMediaManager.h"
|
||||
#include "IMissionManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "LedControl.h"
|
||||
#include "LedsHandle.h"
|
||||
#include "MediaTask.h"
|
||||
#include "MediaTaskHandle.h"
|
||||
#include "MissionStateMachine.h"
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
MediaHandleState::MediaHandleState() : State("MediaHandleState")
|
||||
{
|
||||
mEventHandle[InternalStateEvent::RESET_KEY_MEDIA_TASK] =
|
||||
std::bind(&MediaHandleState::ResetKeyMediaTaskHandle, this, _1);
|
||||
mEventHandle[InternalStateEvent::MEDIA_HANDLE_STATE_TASK_FINISHED] =
|
||||
std::bind(&MediaHandleState::MediaTaskFinishedHandle, this, _1);
|
||||
}
|
||||
void MediaHandleState::GoInState()
|
||||
{
|
||||
|
@ -32,16 +44,45 @@ void MediaHandleState::GoInState()
|
|||
void MediaHandleState::GoOutState()
|
||||
{
|
||||
LogInfo(" ========== MediaHandleState::GoOutState.\n");
|
||||
LedsHandle::DeleteAllLeds();
|
||||
}
|
||||
bool MediaHandleState::ExecuteStateMsg(VStateMachineData *msg)
|
||||
{
|
||||
return DataProcessing::EventHandle(msg);
|
||||
}
|
||||
void MediaHandleState::TaskResponse(const std::vector<MediaTaskResponse> &response)
|
||||
void MediaHandleState::TaskResponse(const MediaTaskInfo &taskinfo)
|
||||
{
|
||||
std::shared_ptr<VMissionData> message = std::make_shared<VMissionDataV2<MediaTaskInfo>>(
|
||||
static_cast<MissionEvent>(InternalStateEvent::MEDIA_HANDLE_STATE_TASK_FINISHED), taskinfo);
|
||||
MissionStateMachine::GetInstance()->SendStateMessage(message);
|
||||
}
|
||||
bool MediaHandleState::ResetKeyMediaTaskHandle(VStateMachineData *msg)
|
||||
{
|
||||
MakeSingleTask(InternalStateEvent::RESET_KEY_MEDIA_TASK, shared_from_this());
|
||||
MediaTaskHandle::MakeSingleTask(InternalStateEvent::RESET_KEY_MEDIA_TASK, shared_from_this());
|
||||
LedsHandle::ControlDeviceStatusLed(
|
||||
DeviceStatus::TAKING_PICTURE_OR_VIDEO, KEEP_ALIVE_FOREVER, BLINKING_SUPER_FAST_MS);
|
||||
return EXECUTED;
|
||||
}
|
||||
bool MediaHandleState::MediaTaskFinishedHandle(VStateMachineData *msg)
|
||||
{
|
||||
std::shared_ptr<MissionMessage> message = std::dynamic_pointer_cast<MissionMessage>(msg->GetMessageObj());
|
||||
std::shared_ptr<VMissionDataV2<MediaTaskInfo>> data =
|
||||
std::dynamic_pointer_cast<VMissionDataV2<MediaTaskInfo>>(message->mMissionData);
|
||||
LogInfo("response files = %d.\n", data->mData.mResponse.size());
|
||||
std::vector<SyncFileInfo> files;
|
||||
for (auto &response : data->mData.mResponse) {
|
||||
auto fileSize = MediaTask::GetFileSize_KB(response.mFileName.c_str());
|
||||
SyncFileInfo file(data->mData.mSerialNumber,
|
||||
response.mFileName,
|
||||
fileSize,
|
||||
response.mDuration_ms,
|
||||
data->mData.mCreateTime_s,
|
||||
FileCreateType::MANUAL_TEST,
|
||||
FileStatus::FINISHED_RECORD);
|
||||
files.push_back(file);
|
||||
}
|
||||
IFilesManager::GetInstance()->SaveFiles(files);
|
||||
LedsHandle::DeleteDeviceStatusLed();
|
||||
MissionStateMachine::GetInstance()->SwitchState(SystemState::IDLE_STATE);
|
||||
return EXECUTED;
|
||||
}
|
|
@ -16,11 +16,13 @@
|
|||
#define MEDIA_HANDLE_STATE_H
|
||||
#include "DataProcessing.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "LedsHandle.h"
|
||||
#include "MediaTaskHandle.h"
|
||||
class MediaHandleState : public State,
|
||||
public DataProcessing,
|
||||
public MediaTaskHandle,
|
||||
public VMediaTaskIniator,
|
||||
public LedsHandle,
|
||||
public std::enable_shared_from_this<MediaHandleState>
|
||||
{
|
||||
public:
|
||||
|
@ -31,7 +33,8 @@ public:
|
|||
bool ExecuteStateMsg(VStateMachineData *msg) override;
|
||||
|
||||
private:
|
||||
void TaskResponse(const std::vector<MediaTaskResponse> &response) override;
|
||||
void TaskResponse(const MediaTaskInfo &taskinfo) override;
|
||||
bool ResetKeyMediaTaskHandle(VStateMachineData *msg);
|
||||
bool MediaTaskFinishedHandle(VStateMachineData *msg);
|
||||
};
|
||||
#endif
|
|
@ -13,13 +13,149 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "MediaTask.h"
|
||||
#include "DataProcessing.h"
|
||||
#include "IIpcConfig.h"
|
||||
#include "ILog.h"
|
||||
#include "IMediaManager.h"
|
||||
#include <cctype>
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <sys/stat.h>
|
||||
#include <vector>
|
||||
MediaTask::MediaTask(const MediaTaskType &type, const InternalStateEvent &bindEvent,
|
||||
const std::weak_ptr<VMediaTaskIniator> &iniator)
|
||||
: mType(type), mBindEvent(bindEvent), mIniator(iniator)
|
||||
const std::weak_ptr<VMediaTaskIniator> &iniator, const unsigned long &serialNumber,
|
||||
const std::string &savePath)
|
||||
: mType(type), mBindEvent(bindEvent), mIniator(iniator), mSerialNumber(serialNumber), mSavePath(savePath),
|
||||
mCreateTime_s(0)
|
||||
{
|
||||
mResponseData.reset();
|
||||
mTargetName.clear();
|
||||
}
|
||||
unsigned int MediaTask::GetTaskTimeOutMs(void)
|
||||
{
|
||||
return MEDIA_TASK_TIMEOUT_MS;
|
||||
}
|
||||
const MediaTaskType MediaTask::GetTaskType(void)
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
std::string MediaTask::GetTargetNameForSaving(void)
|
||||
{
|
||||
if (!mTargetName.empty()) {
|
||||
return mTargetName;
|
||||
}
|
||||
auto now = std::chrono::system_clock::now();
|
||||
|
||||
mCreateTime_s = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();
|
||||
const std::string fileType = MediaTaskType::TAKE_VIDEO == mType ? ".mp4" : ".jpeg";
|
||||
return CreateFileName(mSerialNumber, mSavePath, fileType);
|
||||
}
|
||||
std::string MediaTask::GetThumbnailNameForSaving(const std::string &targetName)
|
||||
{
|
||||
return MediaTask::GetThumbnailNameByTargetName(targetName);
|
||||
}
|
||||
int MediaTask::GetVideoDuration_ms(void)
|
||||
{
|
||||
return DEFAULT_VIDEO_DURATION_MS;
|
||||
}
|
||||
void MediaTask::Response(const std::vector<MediaTaskResponse> &response)
|
||||
{
|
||||
LogInfo("Response handle.\n");
|
||||
auto iniator = mIniator.lock();
|
||||
if (mIniator.expired()) {
|
||||
LogWarning("mIniator is expired.\n");
|
||||
return;
|
||||
}
|
||||
MediaTaskInfo info = {
|
||||
.mResponse = response,
|
||||
.mSerialNumber = mSerialNumber,
|
||||
.mCreateTime_s = mCreateTime_s,
|
||||
};
|
||||
iniator->TaskResponse(info);
|
||||
}
|
||||
std::string MediaTask::GetThumbnailNameByTargetName(const std::string &targetName)
|
||||
{
|
||||
// const std::string fileType = MediaTaskType::TAKE_VIDEO == mType ? ".mp4" : ".jpeg";
|
||||
std::string thumbnailName = targetName;
|
||||
size_t dot_pos = thumbnailName.find_last_of('.');
|
||||
if (dot_pos != std::string::npos) {
|
||||
std::string extension = thumbnailName.substr(dot_pos);
|
||||
if (extension == ".mp4" || extension == ".jpeg") {
|
||||
thumbnailName.replace(dot_pos, extension.length(), "-thumbnail.jpeg");
|
||||
LogInfo("GetThumbnailNameForSaving: %s\n", thumbnailName.c_str());
|
||||
return thumbnailName;
|
||||
}
|
||||
}
|
||||
LogError("TargetName is not a mp4 file.\n");
|
||||
std::string unknowFile = "unknow";
|
||||
return unknowFile;
|
||||
}
|
||||
long long MediaTask::GetCreateTime_s(void)
|
||||
{
|
||||
auto now = std::chrono::system_clock::now();
|
||||
// time_t t_now = std::chrono::system_clock::to_time_t(now);
|
||||
// struct tm tm_now = *std::localtime(&t_now);
|
||||
|
||||
return std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();
|
||||
}
|
||||
int MediaTask::GetFileSize_KB(const char *filePath)
|
||||
{
|
||||
struct stat fileInfo;
|
||||
if (stat(filePath, &fileInfo) != 0) {
|
||||
LogError("stat failed.\n");
|
||||
return FILE_SIZE_ERROR;
|
||||
}
|
||||
return static_cast<double>(fileInfo.st_size) / 1024.0;
|
||||
}
|
||||
MediaTaskType MediaTask::WorkModeConvert(const WorkMode &mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case WorkMode::MODE_PIC:
|
||||
return MediaTaskType::TAKE_PICTURE;
|
||||
case WorkMode::MODE_VIDEO:
|
||||
return MediaTaskType::TAKE_VIDEO;
|
||||
case WorkMode::MODE_PIC_VIDEO:
|
||||
return MediaTaskType::TAKE_PICTURE_AND_VIDEO;
|
||||
|
||||
default:
|
||||
LogWarning("unknow work mode.\n");
|
||||
return MediaTaskType::TAKE_PICTURE_AND_VIDEO;
|
||||
}
|
||||
}
|
||||
std::string MediaTask::GetFileNameBySeriaNumber(const unsigned long &serialNumber, const std::string &sourceFile,
|
||||
const std::string &savePaht)
|
||||
{
|
||||
std::string fileType = "";
|
||||
size_t dot_pos = sourceFile.find_last_of('.');
|
||||
if (dot_pos != std::string::npos) {
|
||||
std::string extension = sourceFile.substr(dot_pos);
|
||||
fileType = extension;
|
||||
}
|
||||
return CreateFileName(serialNumber, savePaht, fileType);
|
||||
}
|
||||
std::string MediaTask::CreateFileName(const unsigned long &serialNumber, const std::string &savePaht,
|
||||
const std::string &fileType)
|
||||
{
|
||||
auto now = std::chrono::system_clock::now();
|
||||
time_t t_now = std::chrono::system_clock::to_time_t(now);
|
||||
struct tm tm_now = *std::localtime(&t_now);
|
||||
/**
|
||||
* @brief When the sequence number is 0, it indicates an invalid sequence number and is replaced by "???".
|
||||
*
|
||||
*/
|
||||
const std::string serialNumberString = 0 == serialNumber ? "???" : std::to_string(serialNumber);
|
||||
int hour = tm_now.tm_hour;
|
||||
int minute = tm_now.tm_min;
|
||||
int second = tm_now.tm_sec;
|
||||
std::ostringstream pathStream;
|
||||
pathStream << savePaht << "xak47-" << serialNumberString << "-" << std::setw(2) << std::setfill('0') << hour
|
||||
<< std::setw(2) << std::setfill('0') << minute << std::setw(2) << std::setfill('0') << second
|
||||
<< fileType;
|
||||
return pathStream.str();
|
||||
}
|
|
@ -15,28 +15,60 @@
|
|||
#ifndef MEDIA_TASK_H
|
||||
#define MEDIA_TASK_H
|
||||
#include "DataProcessing.h"
|
||||
#include "IIpcConfig.h"
|
||||
#include "IMediaManager.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
constexpr int FILE_SIZE_ERROR = -1;
|
||||
constexpr unsigned int MEDIA_TASK_TIMEOUT_MS = 1000 * 60;
|
||||
constexpr int DEFAULT_VIDEO_DURATION_MS = 1000 * 10;
|
||||
typedef struct media_task_info
|
||||
{
|
||||
const std::vector<MediaTaskResponse> mResponse;
|
||||
const unsigned long mSerialNumber;
|
||||
const long long mCreateTime_s;
|
||||
} MediaTaskInfo;
|
||||
class VMediaTaskIniator
|
||||
{
|
||||
public:
|
||||
VMediaTaskIniator() = default;
|
||||
virtual ~VMediaTaskIniator() = default;
|
||||
virtual void TaskResponse(const std::vector<MediaTaskResponse> &response) = 0;
|
||||
virtual void TaskResponse(const MediaTaskInfo &taskinfo) = 0;
|
||||
};
|
||||
class MediaTask : public VMediaTask
|
||||
{
|
||||
public:
|
||||
MediaTask(const MediaTaskType &type, const InternalStateEvent &bindEvent,
|
||||
const std::weak_ptr<VMediaTaskIniator> &iniator);
|
||||
const std::weak_ptr<VMediaTaskIniator> &iniator, const unsigned long &serialNumber,
|
||||
const std::string &savePath);
|
||||
virtual ~MediaTask() = default;
|
||||
virtual unsigned int GetTaskTimeOutMs(void);
|
||||
const MediaTaskType GetTaskType(void) override;
|
||||
std::string GetTargetNameForSaving(void) override;
|
||||
std::string GetThumbnailNameForSaving(const std::string &targetName) override;
|
||||
int GetVideoDuration_ms(void) override;
|
||||
void Response(const std::vector<MediaTaskResponse> &response) override;
|
||||
|
||||
public:
|
||||
static std::string GetThumbnailNameByTargetName(const std::string &targetName);
|
||||
static long long GetCreateTime_s(void);
|
||||
static int GetFileSize_KB(const char *filePath);
|
||||
static MediaTaskType WorkModeConvert(const WorkMode &mode);
|
||||
static std::string GetFileNameBySeriaNumber(const unsigned long &serialNumber, const std::string &sourceFile,
|
||||
const std::string &savePaht);
|
||||
static std::string CreateFileName(const unsigned long &serialNumber, const std::string &savePaht,
|
||||
const std::string &fileType);
|
||||
|
||||
private:
|
||||
const MediaTaskType mType;
|
||||
const InternalStateEvent mBindEvent;
|
||||
const std::weak_ptr<VMediaTaskIniator> mIniator;
|
||||
const unsigned long mSerialNumber;
|
||||
const std::string mSavePath;
|
||||
bool mFinished = false;
|
||||
std::shared_ptr<MediaTaskResponse> mResponseData;
|
||||
std::string mTargetName;
|
||||
long long mCreateTime_s;
|
||||
std::vector<std::string> mTargetNameList;
|
||||
};
|
||||
#endif
|
|
@ -13,8 +13,16 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "MediaTaskHandle.h"
|
||||
#include "DataProcessing.h"
|
||||
#include "IFilesManager.h"
|
||||
#include "IIpcConfig.h"
|
||||
#include "ILog.h"
|
||||
#include "IMediaManager.h"
|
||||
#include "IMissionManager.h"
|
||||
#include "MediaTask.h"
|
||||
#include "MissionStateMachine.h"
|
||||
#include "StatusCode.h"
|
||||
#include <memory>
|
||||
MediaTaskHandle::MediaTaskHandle()
|
||||
{
|
||||
mMediaHandle.reset();
|
||||
|
@ -32,14 +40,19 @@ void MediaTaskHandle::UnInit(void)
|
|||
void MediaTaskHandle::MakeSingleTask(const InternalStateEvent &bindEvent,
|
||||
const std::shared_ptr<VMediaTaskIniator> &iniator)
|
||||
{
|
||||
std::shared_ptr<VMediaTask> task = std::make_shared<MediaTask>(MediaTaskType::END, bindEvent, iniator);
|
||||
InfoToBeSaved info = IFilesManager::GetInstance()->GetInfoForSavingFiles(1);
|
||||
WorkMode workMode = IIpcConfig::GetInstance()->GetWorkMode();
|
||||
MediaTaskType taskType = MediaTask::WorkModeConvert(workMode);
|
||||
LogInfo("taskType: %s\n", IMediaManager::PrintfTaskType(taskType));
|
||||
std::shared_ptr<VMediaTask> task =
|
||||
std::make_shared<MediaTask>(taskType, bindEvent, iniator, info.mSerialNumber, info.mSavingPath);
|
||||
if (!mMediaHandle) {
|
||||
LogError("MediaHandle is null");
|
||||
return;
|
||||
}
|
||||
auto code = mMediaHandle->ExecuteTask(task);
|
||||
if (IsCodeOK(code)) {
|
||||
mRuningTask = task;
|
||||
mRuningTask = task; // task should be saved here.
|
||||
long long timeOut = std::dynamic_pointer_cast<MediaTask>(task)->GetTaskTimeOutMs();
|
||||
std::shared_ptr<VMissionData> message = std::make_shared<VMissionData>(
|
||||
static_cast<MissionEvent>(InternalStateEvent::MEDIA_HANDLE_STATE_TASK_TIME_OUT));
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef MEDIA_TASK_HANDLE_H
|
||||
#define MEDIA_TASK_HANDLE_H
|
||||
#include "DataProcessing.h"
|
||||
#include "IIpcConfig.h"
|
||||
#include "IMediaManager.h"
|
||||
#include "MediaTask.h"
|
||||
class MediaTaskHandle
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "MissionManager.h"
|
||||
#include "IAppManager.h"
|
||||
#include "MissionStateMachine.h"
|
||||
#include "StatusCode.h"
|
||||
const StatusCode MissionManager::Init(void)
|
||||
{
|
||||
MissionStateMachine::GetInstance()->Init();
|
||||
|
|
|
@ -13,17 +13,23 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "MissionManagerMakePtr.h"
|
||||
#include "FormattingState.h"
|
||||
#include "ILog.h"
|
||||
#include "IMcuManager.h"
|
||||
#include "IMissionManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "IdleState.h"
|
||||
#include "MediaHandleState.h"
|
||||
#include "MissionManager.h"
|
||||
#include "OnMissionState.h"
|
||||
#include "PirTriggeredMissionState.h"
|
||||
#include "SdCardHandleState.h"
|
||||
#include "StatusCode.h"
|
||||
#include "StorageHandleState.h"
|
||||
#include "TestMissionState.h"
|
||||
#include "TopState.h"
|
||||
#include "UpgradeState.h"
|
||||
#include <memory>
|
||||
bool CreateMissionManagerModule(void)
|
||||
{
|
||||
auto instance = std::make_shared<IMissionManager>();
|
||||
|
@ -115,4 +121,9 @@ std::shared_ptr<State> MissionManagerMakePtr::CreateIdleState(void)
|
|||
{
|
||||
std::shared_ptr<State> state = std::make_shared<IdleState>();
|
||||
return state;
|
||||
}
|
||||
std::shared_ptr<State> MissionManagerMakePtr::CreateFormattingState(void)
|
||||
{
|
||||
std::shared_ptr<State> state = std::make_shared<FormattingState>();
|
||||
return state;
|
||||
}
|
|
@ -33,5 +33,6 @@ public:
|
|||
virtual std::shared_ptr<State> CreateUpgradeState(void);
|
||||
virtual std::shared_ptr<State> CreateMediaHandleState(void);
|
||||
virtual std::shared_ptr<State> CreateIdleState(void);
|
||||
virtual std::shared_ptr<State> CreateFormattingState(void);
|
||||
};
|
||||
#endif
|
|
@ -13,9 +13,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "MissionState.h"
|
||||
#include "IAppManager.h"
|
||||
#include "DataProcessing.h"
|
||||
#include "ILog.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "LedsHandle.h"
|
||||
#include "MissionStateMachine.h"
|
||||
#include <functional>
|
||||
#include <string>
|
||||
MissionState::MissionState(const std::string &name) : State(name)
|
||||
{
|
||||
mEventHandle[InternalStateEvent::MEDIA_REPORT_EVENT] = std::bind(&MissionState::MediaReportHandle, this, _1);
|
||||
|
@ -38,6 +42,25 @@ bool MissionState::ExecuteStateMsg(VStateMachineData *msg)
|
|||
}
|
||||
bool MissionState::MediaReportHandle(VStateMachineData *msg)
|
||||
{
|
||||
LogInfo("Get media file from chip.\n");
|
||||
// std::shared_ptr<MissionMessage> message = std::dynamic_pointer_cast<MissionMessage>(msg->GetMessageObj());
|
||||
// std::shared_ptr<VMissionDataV2<MediaReportEvent>> data =
|
||||
// std::dynamic_pointer_cast<VMissionDataV2<MediaReportEvent>>(message->mMissionData);
|
||||
// if (!data) {
|
||||
// LogError("nullptr pointer.\n");
|
||||
// return NOT_EXECUTED;
|
||||
// }
|
||||
// auto fileSize = MediaTask::GetFileSize_KB(data->mData.mFileName.c_str());
|
||||
// auto createTime = MediaTask::GetCreateTime_s();
|
||||
// auto createType = MissionStateMachine::GetInstance()->GetFileCreateType();
|
||||
// SyncFileInfo file(UNDEFINE_SERIAL_NUMBER,
|
||||
// data->mData.mFileName,
|
||||
// fileSize,
|
||||
// data->mData.mDuration_ms,
|
||||
// createTime,
|
||||
// createType,
|
||||
// FileStatus::FINISHED_RECORD);
|
||||
// mFastStartMediaFiles.push_back(file);
|
||||
MissionStateMachine::GetInstance()->DelayMessage(msg);
|
||||
MissionStateMachine::GetInstance()->SwitchState(SystemState::STORAGE_HANDLE_STATE);
|
||||
return EXECUTED;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef MISSION_STATE_H
|
||||
#define MISSION_STATE_H
|
||||
#include "DataProcessing.h"
|
||||
#include "IFilesManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "LedsHandle.h"
|
||||
class MissionState : public State,
|
||||
|
@ -33,7 +34,17 @@ protected:
|
|||
bool SdCardEventReportHandle(VStateMachineData *msg);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Processes media events actively reported by the bottom layer, and refers to snapshot or video recording
|
||||
* during quick start.
|
||||
* @param msg
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
bool MediaReportHandle(VStateMachineData *msg);
|
||||
bool CheckUpgradeFileHandle(VStateMachineData *msg);
|
||||
|
||||
private:
|
||||
std::vector<SyncFileInfo> mFastStartMediaFiles;
|
||||
};
|
||||
#endif
|
|
@ -14,9 +14,16 @@
|
|||
*/
|
||||
#include "MissionStateMachine.h"
|
||||
#include "DataProcessing.h"
|
||||
#include "IFilesManager.h"
|
||||
#include "ILog.h"
|
||||
#include "IMcuManager.h"
|
||||
#include "IMissionManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "McuAskBase.h"
|
||||
#include "MissionManagerMakePtr.h"
|
||||
#include "StatusCode.h"
|
||||
#include "VStateBase.h"
|
||||
#include <memory>
|
||||
// #include "TopState.h"
|
||||
std::shared_ptr<MissionStateMachine> &MissionStateMachine::GetInstance(std::shared_ptr<MissionStateMachine> *impl)
|
||||
{
|
||||
|
@ -52,6 +59,7 @@ void MissionStateMachine::Init(void)
|
|||
void MissionStateMachine::UnInit(void)
|
||||
{
|
||||
mStateMachine->StopHandlerThread();
|
||||
UnInitAllState();
|
||||
mStateTree.clear();
|
||||
}
|
||||
StatusCode MissionStateMachine::SendStateMessage(const std::shared_ptr<VMissionData> &message)
|
||||
|
@ -75,6 +83,19 @@ void MissionStateMachine::SwitchState(const SystemState &state)
|
|||
{
|
||||
mStateMachine->SwitchState(mStateTree[state].get());
|
||||
}
|
||||
FileCreateType MissionStateMachine::GetFileCreateType(void)
|
||||
{
|
||||
switch (mStartMission) {
|
||||
case IpcMission::TEST:
|
||||
return FileCreateType::MANUAL_TEST;
|
||||
case IpcMission::PIR_TRIGGERED:
|
||||
return FileCreateType::PIR;
|
||||
|
||||
default:
|
||||
LogError("unknow ipcmission.\n");
|
||||
return FileCreateType::END;
|
||||
}
|
||||
}
|
||||
IpcMission MissionStateMachine::GetStartMission(void)
|
||||
{
|
||||
class McuAskIpcMission : public McuAsk<IpcMission>, public McuAskBase
|
||||
|
@ -101,8 +122,10 @@ void MissionStateMachine::RunStateMachine(const IpcMission &mission)
|
|||
mStateTree[SystemState::UPGRADE_STATE] = MissionManagerMakePtr::GetInstance()->CreateUpgradeState();
|
||||
mStateTree[SystemState::MEDIA_HANDLE_STATE] = MissionManagerMakePtr::GetInstance()->CreateMediaHandleState();
|
||||
mStateTree[SystemState::IDLE_STATE] = MissionManagerMakePtr::GetInstance()->CreateIdleState();
|
||||
mStateTree[SystemState::FORMATTING_STATE] = MissionManagerMakePtr::GetInstance()->CreateFormattingState();
|
||||
mStateMachine->StatePlus(mStateTree[SystemState::TOP_STATE].get(), nullptr);
|
||||
mStateMachine->StatePlus(mStateTree[SystemState::MISSION_STATE].get(), mStateTree[SystemState::TOP_STATE].get());
|
||||
mStateMachine->StatePlus(mStateTree[SystemState::FORMATTING_STATE].get(), mStateTree[SystemState::TOP_STATE].get());
|
||||
mStateMachine->StatePlus(mStateTree[SystemState::STORAGE_HANDLE_STATE].get(),
|
||||
mStateTree[SystemState::MISSION_STATE].get());
|
||||
mStateMachine->StatePlus(mStateTree[SystemState::SD_CARD_HANDLE_STATE].get(),
|
||||
|
@ -114,11 +137,23 @@ void MissionStateMachine::RunStateMachine(const IpcMission &mission)
|
|||
mStateMachine->StatePlus(mStateTree[SystemState::IDLE_STATE].get(), mStateTree[SystemState::MISSION_STATE].get());
|
||||
mStateMachine->SetCurrentState(mStateTree[SystemState::TOP_STATE].get());
|
||||
mStateMachine->StartStateMachine();
|
||||
/**
|
||||
* @brief The business can only be processed after the state machine is started.
|
||||
*
|
||||
*/
|
||||
std::shared_ptr<VMissionData> message =
|
||||
std::make_shared<VMissionData>(static_cast<MissionEvent>(InternalStateEvent::STORAGE_HANDLE_STATE_INIT));
|
||||
SendStateMessage(message);
|
||||
InitAllState();
|
||||
}
|
||||
void MissionStateMachine::InitAllState(void)
|
||||
{
|
||||
for (auto &state : mStateTree) {
|
||||
std::shared_ptr<VStateBase> stateBase = std::dynamic_pointer_cast<VStateBase>(state.second);
|
||||
if (stateBase) {
|
||||
stateBase->StateInit();
|
||||
}
|
||||
}
|
||||
}
|
||||
void MissionStateMachine::UnInitAllState(void)
|
||||
{
|
||||
for (auto &state : mStateTree) {
|
||||
std::shared_ptr<VStateBase> stateBase = std::dynamic_pointer_cast<VStateBase>(state.second);
|
||||
if (stateBase) {
|
||||
stateBase->StateUnInit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef MISSION_STATE_MACHINE_H
|
||||
#define MISSION_STATE_MACHINE_H
|
||||
// #include "IDeviceManager.h"
|
||||
#include "IFilesManager.h"
|
||||
#include "IMcuManager.h"
|
||||
#include "IMissionManager.h"
|
||||
#include "IStateMachine.h"
|
||||
|
@ -22,6 +23,8 @@
|
|||
#include <map>
|
||||
const bool NOT_EXECUTED = false;
|
||||
const bool EXECUTED = true;
|
||||
constexpr bool FATHER_HANDLE_MESSAGE = NOT_EXECUTED;
|
||||
constexpr bool HANDLE_HELPESS = EXECUTED;
|
||||
enum class SystemState
|
||||
{
|
||||
TOP_STATE = 0,
|
||||
|
@ -31,6 +34,7 @@ enum class SystemState
|
|||
UPGRADE_STATE,
|
||||
MEDIA_HANDLE_STATE,
|
||||
IDLE_STATE,
|
||||
FORMATTING_STATE,
|
||||
END
|
||||
};
|
||||
class MissionStateMachine
|
||||
|
@ -45,10 +49,18 @@ public:
|
|||
StatusCode MessageExecutedLater(const std::shared_ptr<VMissionData> &message, long long &delayTimeMs);
|
||||
void DelayMessage(VStateMachineData *msg);
|
||||
void SwitchState(const SystemState &state);
|
||||
/**
|
||||
* @brief Get the type of quick snapshot or video file based on the startup task parameters.
|
||||
*
|
||||
* @return FileCreateType
|
||||
*/
|
||||
FileCreateType GetFileCreateType(void);
|
||||
|
||||
private:
|
||||
IpcMission GetStartMission(void);
|
||||
void RunStateMachine(const IpcMission &mission);
|
||||
void InitAllState(void);
|
||||
void UnInitAllState(void);
|
||||
|
||||
private:
|
||||
std::shared_ptr<VStateMachineHandle> mStateMachine;
|
||||
|
|
|
@ -14,12 +14,11 @@
|
|||
*/
|
||||
#include "OnMissionState.h"
|
||||
#include "ILog.h"
|
||||
#include "IStorageManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "MissionState.h"
|
||||
#include "MissionStateMachine.h"
|
||||
OnMissionState::OnMissionState() : MissionState("OnMissionState")
|
||||
{
|
||||
// mEventHandle[InternalStateEvent::ANY_STATE_SD_STATUS_PERORIED] =
|
||||
// std::bind(&OnMissionState::SdCardEventReportSendToApp, this, _1);
|
||||
}
|
||||
void OnMissionState::GoInState()
|
||||
{
|
||||
|
|
|
@ -12,14 +12,13 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "PirTriggeredMissionState.h"
|
||||
#include "ILog.h"
|
||||
#include "IStorageManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "MissionState.h"
|
||||
#include "MissionStateMachine.h"
|
||||
#include "PirTriggeredMissionState.h"
|
||||
PirTriggeredMissionState::PirTriggeredMissionState() : MissionState("PirTriggeredMissionState")
|
||||
{
|
||||
// mEventHandle[InternalStateEvent::ANY_STATE_SD_STATUS_PERORIED] =
|
||||
// std::bind(&PirTriggeredMissionState::SdCardEventReportSendToApp, this, _1);
|
||||
}
|
||||
void PirTriggeredMissionState::GoInState()
|
||||
{
|
||||
|
|
|
@ -13,15 +13,31 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "SdCardHandleState.h"
|
||||
#include "DataProcessing.h"
|
||||
#include "IFilesManager.h"
|
||||
#include "ILog.h"
|
||||
#include "IMediaManager.h"
|
||||
#include "IMissionManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "IStorageManager.h"
|
||||
#include "LedControl.h"
|
||||
#include "LedsHandle.h"
|
||||
#include "MediaTask.h"
|
||||
#include "MissionStateMachine.h"
|
||||
#include "StatusCode.h"
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
using std::placeholders::_1;
|
||||
SdCardHandleState::SdCardHandleState() : State("SdCardHandleState"), mSdCardStatus(StorageEvent::END)
|
||||
{
|
||||
mEventHandle[InternalStateEvent::MEDIA_REPORT_EVENT] = std::bind(&SdCardHandleState::MediaReportHandle, this, _1);
|
||||
mEventHandle[InternalStateEvent::SD_CARD_HANDLE_STATE_SD_STATUS_REPORTED] =
|
||||
std::bind(&SdCardHandleState::SdCardEventHandle, this, _1);
|
||||
mEventHandle[InternalStateEvent::RESET_KEY_MEDIA_TASK] =
|
||||
std::bind(&SdCardHandleState::ResetKeyMediaTaskHandle, this, _1);
|
||||
mEventHandle[InternalStateEvent::FORMAT_KEY_FORMAT_SD_CARD] =
|
||||
std::bind(&SdCardHandleState::FormatKeyFormattingSDCardHandle, this, _1);
|
||||
}
|
||||
void SdCardHandleState::GoInState()
|
||||
{
|
||||
|
@ -35,6 +51,14 @@ bool SdCardHandleState::ExecuteStateMsg(VStateMachineData *msg)
|
|||
{
|
||||
return DataProcessing::EventHandle(msg);
|
||||
}
|
||||
void SdCardHandleState::StateInit(void)
|
||||
{
|
||||
}
|
||||
void SdCardHandleState::StateUnInit(void)
|
||||
{
|
||||
IFilesManager::GetInstance()->UnInit();
|
||||
LedsHandle::DeleteAllLeds();
|
||||
}
|
||||
bool SdCardHandleState::MediaReportHandle(VStateMachineData *msg)
|
||||
{
|
||||
LogInfo(" MediaReportHandle.\n");
|
||||
|
@ -45,20 +69,37 @@ bool SdCardHandleState::MediaReportHandle(VStateMachineData *msg)
|
|||
LogError("nullptr pointer.\n");
|
||||
return NOT_EXECUTED;
|
||||
}
|
||||
InfoToBeSaved info = IFilesManager::GetInstance()->GetInfoForSavingFiles(1);
|
||||
auto targetFile = MediaTask::GetFileNameBySeriaNumber(info.mSerialNumber, data->mData.mFileName, info.mSavingPath);
|
||||
auto fileSize = MediaTask::GetFileSize_KB(data->mData.mFileName.c_str());
|
||||
auto createTime = MediaTask::GetCreateTime_s();
|
||||
auto createType = MissionStateMachine::GetInstance()->GetFileCreateType();
|
||||
SyncFileInfo file(info.mSerialNumber,
|
||||
// data->mData.mFileName,
|
||||
targetFile,
|
||||
fileSize,
|
||||
data->mData.mDuration_ms,
|
||||
createTime,
|
||||
createType,
|
||||
FileStatus::FINISHED_RECORD);
|
||||
file.mSourceFile = data->mData.mFileName;
|
||||
if (StorageEvent::SD_CARD_INSERT != mSdCardStatus) {
|
||||
/**
|
||||
* @brief The SD card has not been mounted yet, cache the data for the quick start first.
|
||||
*
|
||||
*/
|
||||
LogWarning("Sd card is not inserted, cache data.\n");
|
||||
mFileNeedToSave = std::make_shared<SaveFileInfo>(data->mData.mFileName);
|
||||
// mFileNeedToSave = std::make_shared<SaveFileInfo>(data->mData.mFileName);
|
||||
mFastStartMediaFiles.push_back(file);
|
||||
return EXECUTED;
|
||||
}
|
||||
LogInfo("file = %s.\n", data->mData.mFileName.c_str());
|
||||
SaveFileInfo saveFileInfo(data->mData.mFileName);
|
||||
StatusCode code = IFilesManager::GetInstance()->SaveFile(saveFileInfo);
|
||||
std::vector<SyncFileInfo> files;
|
||||
files.push_back(file);
|
||||
// SaveFileInfo saveFileInfo(data->mData.mFileName);
|
||||
StatusCode code = IFilesManager::GetInstance()->SaveFiles(files);
|
||||
if (IsCodeOK(code) == false) {
|
||||
LogError("SaveFile failed.\n");
|
||||
LogError("SaveFiles failed.\n");
|
||||
}
|
||||
return EXECUTED;
|
||||
}
|
||||
|
@ -68,19 +109,84 @@ bool SdCardHandleState::SdCardEventHandle(VStateMachineData *msg)
|
|||
std::shared_ptr<VMissionDataV2<StorageEvent>> data =
|
||||
std::dynamic_pointer_cast<VMissionDataV2<StorageEvent>>(message->mMissionData);
|
||||
LogInfo(" SdCardEventHandle event:%s.\n", IStorageManager::GetInstance()->PrintStringStorageEvent(data->mData));
|
||||
if (mFileNeedToSave && StorageEvent::SD_CARD_INSERT == data->mData) {
|
||||
LogInfo("Sd card is inserted for the first time.\n");
|
||||
StatusCode code = IFilesManager::GetInstance()->SaveFile(*(mFileNeedToSave.get()));
|
||||
if (IsCodeOK(code) == false) {
|
||||
LogError("SaveFile failed.\n");
|
||||
}
|
||||
mFileNeedToSave.reset();
|
||||
}
|
||||
// if (!mFastStartMediaFiles.empty() && StorageEvent::SD_CARD_INSERT == data->mData) {
|
||||
// LogInfo("Sd card is inserted for the first time.\n");
|
||||
// // StatusCode code = IFilesManager::GetInstance()->SaveFile(*(mFileNeedToSave.get()));
|
||||
// StatusCode code = IFilesManager::GetInstance()->SaveFiles(mFastStartMediaFiles);
|
||||
// if (IsCodeOK(code) == false) {
|
||||
// LogError("SaveFile failed.\n");
|
||||
// }
|
||||
// // mFileNeedToSave.reset();
|
||||
// mFastStartMediaFiles.clear();
|
||||
// }
|
||||
mSdCardStatus = data->mData;
|
||||
/**
|
||||
* @brief The file management uses a database. When the SD card is inserted or removed, the card's file data needs
|
||||
* to be reinitialized.
|
||||
*/
|
||||
if (StorageEvent::SD_CARD_INSERT == mSdCardStatus) {
|
||||
IFilesManager::GetInstance()->Init();
|
||||
std::shared_ptr<VMissionData> message =
|
||||
std::make_shared<VMissionData>(static_cast<MissionEvent>(InternalStateEvent::CHECK_UPGRADE_FILE));
|
||||
MissionStateMachine::GetInstance()->SendStateMessage(message);
|
||||
if (!mFastStartMediaFiles.empty()) {
|
||||
LogInfo("Sd card is inserted for the first time.\n");
|
||||
// StatusCode code = IFilesManager::GetInstance()->SaveFile(*(mFileNeedToSave.get()));
|
||||
StatusCode code = IFilesManager::GetInstance()->SaveFiles(mFastStartMediaFiles);
|
||||
if (IsCodeOK(code) == false) {
|
||||
LogError("SaveFile failed.\n");
|
||||
}
|
||||
// mFileNeedToSave.reset();
|
||||
mFastStartMediaFiles.clear();
|
||||
}
|
||||
}
|
||||
else {
|
||||
IFilesManager::GetInstance()->UnInit();
|
||||
}
|
||||
SetSdCardLedsStatus(mSdCardStatus);
|
||||
return EXECUTED;
|
||||
}
|
||||
bool SdCardHandleState::ResetKeyMediaTaskHandle(VStateMachineData *msg)
|
||||
{
|
||||
if (StorageEvent::SD_CARD_INSERT == mSdCardStatus) {
|
||||
return FATHER_HANDLE_MESSAGE;
|
||||
}
|
||||
LogWarning("Sd card is not inserted, ignore reset key media task.\n");
|
||||
return HANDLE_HELPESS;
|
||||
}
|
||||
/**
|
||||
* @brief Why do we need to switch status and go through the formatting process here?
|
||||
* This is because the guarantee business requires that the SD card be formatted safely under the condition that the SD
|
||||
* card is not occupied.
|
||||
* @param msg
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
bool SdCardHandleState::FormatKeyFormattingSDCardHandle(VStateMachineData *msg)
|
||||
{
|
||||
if (StorageEvent::SD_CARD_INSERT == mSdCardStatus || StorageEvent::SD_ABNORMAL == mSdCardStatus) {
|
||||
LogInfo("FormatKeyFormattingSDCardHandle.\n");
|
||||
MissionStateMachine::GetInstance()->DelayMessage(msg);
|
||||
MissionStateMachine::GetInstance()->SwitchState(SystemState::FORMATTING_STATE);
|
||||
return EXECUTED;
|
||||
}
|
||||
LogWarning("Sd card is not inserted, ignore format key.\n");
|
||||
return EXECUTED;
|
||||
}
|
||||
void SdCardHandleState::SetSdCardLedsStatus(const StorageEvent &event)
|
||||
{
|
||||
switch (event) {
|
||||
case StorageEvent::SD_CARD_REMOVE:
|
||||
LedsHandle::ControlDeviceStatusLed(DeviceStatus::SD_CARD_REMOVE, KEEP_ALIVE_FOREVER, BLINKING_SLOW_MS);
|
||||
break;
|
||||
case StorageEvent::SD_CARD_INSERT:
|
||||
LedsHandle::DeleteDeviceStatusLed();
|
||||
break;
|
||||
case StorageEvent::SD_ABNORMAL:
|
||||
LedsHandle::ControlDeviceStatusLed(DeviceStatus::SD_CARD_ABNORMAL, KEEP_ALIVE_FOREVER, BLINKING_SUPER_FAST_MS);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -19,7 +19,13 @@
|
|||
#include "IMediaManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "IStorageManager.h"
|
||||
class SdCardHandleState : public State, public DataProcessing, public std::enable_shared_from_this<SdCardHandleState>
|
||||
#include "LedsHandle.h"
|
||||
#include "VStateBase.h"
|
||||
class SdCardHandleState : public State,
|
||||
public DataProcessing,
|
||||
public LedsHandle,
|
||||
public VStateBase,
|
||||
public std::enable_shared_from_this<SdCardHandleState>
|
||||
{
|
||||
public:
|
||||
SdCardHandleState();
|
||||
|
@ -29,11 +35,17 @@ public:
|
|||
bool ExecuteStateMsg(VStateMachineData *msg) override;
|
||||
|
||||
protected:
|
||||
void StateInit(void) override;
|
||||
void StateUnInit(void) override;
|
||||
bool MediaReportHandle(VStateMachineData *msg);
|
||||
bool SdCardEventHandle(VStateMachineData *msg);
|
||||
bool ResetKeyMediaTaskHandle(VStateMachineData *msg);
|
||||
bool FormatKeyFormattingSDCardHandle(VStateMachineData *msg);
|
||||
void SetSdCardLedsStatus(const StorageEvent &event);
|
||||
|
||||
private:
|
||||
StorageEvent mSdCardStatus;
|
||||
std::shared_ptr<SaveFileInfo> mFileNeedToSave;
|
||||
std::shared_ptr<SaveFileInfo> mFileNeedToSave; // TODO: delete.
|
||||
std::vector<SyncFileInfo> mFastStartMediaFiles;
|
||||
};
|
||||
#endif
|
|
@ -13,6 +13,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "SetLedState.h"
|
||||
#include "IDeviceManager.h"
|
||||
#include "LedControl.h"
|
||||
#include "StatusCode.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
SetLedState::SetLedState(const LedState &state, const unsigned int &keepAliveTime, const unsigned int &blinkPeriod)
|
||||
: mState(state), mKeepAliveTime(keepAliveTime), mBlinkPeriod(blinkPeriod)
|
||||
{
|
||||
|
|
|
@ -13,13 +13,17 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "StorageHandleState.h"
|
||||
#include "DataProcessing.h"
|
||||
#include "ILog.h"
|
||||
#include "IMediaManager.h"
|
||||
#include "IMissionManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "IStorageManager.h"
|
||||
#include "MissionStateMachine.h"
|
||||
#include <memory>
|
||||
StorageHandleState::StorageHandleState() : State("StorageHandleState")
|
||||
{
|
||||
mEventHandle[InternalStateEvent::STORAGE_HANDLE_STATE_INIT] =
|
||||
std::bind(&StorageHandleState::StorageStartInitHandle, this, _1);
|
||||
// mEventHandle[InternalStateEvent::STORAGE_HANDLE_STATE_INIT] =
|
||||
// std::bind(&StorageHandleState::StorageStartInitHandle, this, _1);
|
||||
}
|
||||
void StorageHandleState::GoInState()
|
||||
{
|
||||
|
@ -52,8 +56,10 @@ void StorageHandleState::ReportEvent(const StorageEvent &event)
|
|||
static_cast<MissionEvent>(InternalStateEvent::ANY_STATE_SD_STATUS_PERORIED), event);
|
||||
MissionStateMachine::GetInstance()->SendStateMessage(message2);
|
||||
}
|
||||
bool StorageHandleState::StorageStartInitHandle(VStateMachineData *msg)
|
||||
void StorageHandleState::StateInit(void)
|
||||
{
|
||||
Init();
|
||||
return EXECUTED;
|
||||
}
|
||||
void StorageHandleState::StateUnInit(void)
|
||||
{
|
||||
}
|
|
@ -18,9 +18,11 @@
|
|||
#include "IMediaManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "IStorageManager.h"
|
||||
#include "VStateBase.h"
|
||||
class StorageHandleState : public State,
|
||||
public DataProcessing,
|
||||
public VStorageMoniter,
|
||||
public VStateBase,
|
||||
public std::enable_shared_from_this<StorageHandleState>
|
||||
{
|
||||
public:
|
||||
|
@ -34,6 +36,7 @@ public:
|
|||
|
||||
private: // About VStorageMoniter
|
||||
void ReportEvent(const StorageEvent &event) override;
|
||||
bool StorageStartInitHandle(VStateMachineData *msg);
|
||||
void StateInit(void) override;
|
||||
void StateUnInit(void) override;
|
||||
};
|
||||
#endif
|
|
@ -13,20 +13,38 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "TestMissionState.h"
|
||||
#include "DataProcessing.h"
|
||||
#include "IAppManager.h"
|
||||
#include "ILog.h"
|
||||
#include "IMcuManager.h"
|
||||
#include "IMissionManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "IStorageManager.h"
|
||||
#include "LedControl.h"
|
||||
#include "LedsHandle.h"
|
||||
#include "McuAskBase.h"
|
||||
#include "MissionState.h"
|
||||
#include "MissionStateMachine.h"
|
||||
TestMissionState::TestMissionState() : MissionState("TestMissionState")
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
TestMissionState::TestMissionState()
|
||||
: MissionState("TestMissionState"), mFormattingSDCard(SD_CARD_IS_NOT_FORMATTING), mResetKeyHoldTime(0),
|
||||
mFormatKeyHoldTime(0)
|
||||
{
|
||||
mEventHandle[InternalStateEvent::ANY_STATE_SD_STATUS_PERORIED] =
|
||||
std::bind(&TestMissionState::SdCardEventReportSendToApp, this, _1);
|
||||
mEventHandle[InternalStateEvent::RESET_KEY_MEDIA_TASK] =
|
||||
std::bind(&TestMissionState::ResetKeyMediaTaskHandle, this, _1);
|
||||
mKeyClickHandle["reset"] = std::bind(&TestMissionState::ClickResetKey, this, _1);
|
||||
mKeyHoldDownHandle["reset"] = std::bind(&TestMissionState::HoldDownResetKey, this, _1);
|
||||
mKeyHoldDownHandle["format"] = std::bind(&TestMissionState::HoldDownFormatKey, this, _1);
|
||||
mKeyHoldUpHandle["format"] = std::bind(&TestMissionState::HoldUpFormatKey, this, _1);
|
||||
}
|
||||
void TestMissionState::GoInState()
|
||||
{
|
||||
mFormattingSDCard = SD_CARD_IS_NOT_FORMATTING;
|
||||
mFormatKeyHoldTime = 0;
|
||||
mResetKeyHoldTime = 0;
|
||||
MissionState::GoInState();
|
||||
LogInfo(" ========== TestMissionState::GoInState.\n");
|
||||
AppParam mAppParam(APP_MANAGER_DEVICE_IP, APP_MANAGER_HTTP_SERVER_PORT, APP_MANAGER_TCP_SERVER_PORT); // TODO:
|
||||
|
@ -34,10 +52,11 @@ void TestMissionState::GoInState()
|
|||
std::shared_ptr<VAppMonitor> monitor =
|
||||
std::dynamic_pointer_cast<TestMissionState>(MissionState::shared_from_this());
|
||||
IAppManager::GetInstance()->SetAppMonitor(monitor);
|
||||
ControlDeviceStatusLed(DeviceStatus::NORMAL);
|
||||
LedsHandle::ControlDeviceStatusLed(DeviceStatus::NORMAL, KEEP_ALIVE_FOREVER, BLINKING_SLOW_MS);
|
||||
}
|
||||
void TestMissionState::GoOutState()
|
||||
{
|
||||
IAppManager::GetInstance()->UnInit();
|
||||
MissionState::GoOutState();
|
||||
LogInfo(" ========== TestMissionState::GoOutState.\n");
|
||||
}
|
||||
|
@ -60,14 +79,86 @@ bool TestMissionState::ResetKeyMediaTaskHandle(VStateMachineData *msg)
|
|||
bool TestMissionState::ClickResetKey(const KeyEventData &data)
|
||||
{
|
||||
LogInfo("reset key click:make a media task.\n");
|
||||
// std::shared_ptr<VMissionData> message = std::make_shared<VMissionDataV2<MediaReportEvent>>(
|
||||
// static_cast<MissionEvent>(InternalStateEvent::MEDIA_REPORT_EVENT), event);
|
||||
// MissionStateMachine::GetInstance()->SendStateMessage(message);
|
||||
std::shared_ptr<VMissionData> message =
|
||||
std::make_shared<VMissionData>(static_cast<MissionEvent>(InternalStateEvent::RESET_KEY_MEDIA_TASK));
|
||||
MissionStateMachine::GetInstance()->SendStateMessage(message);
|
||||
return EXECUTED;
|
||||
}
|
||||
bool TestMissionState::HoldDownResetKey(const KeyEventData &data)
|
||||
{
|
||||
constexpr int CLOSE_WATCH_DOG_PRESSING_TIME_MS = 1000 * 3;
|
||||
if (mFormatKeyHoldTime > data.mHoldTime && data.mHoldTime >= CLOSE_WATCH_DOG_PRESSING_TIME_MS &&
|
||||
mResetKeyHoldTime == 0) {
|
||||
LogWarning("Close watch dog.\n");
|
||||
constexpr int KEEP_BLINKING_FAST_MS = 1000 * 3;
|
||||
LedsHandle::ControlDeviceStatusLed(DeviceStatus::CLOSE_WATCHDOG, KEEP_BLINKING_FAST_MS, BLINKING_FAST_MS);
|
||||
CloseWatchDog();
|
||||
}
|
||||
if (CLOSE_WATCH_DOG_PRESSING_TIME_MS > data.mHoldTime) {
|
||||
return NOT_EXECUTED;
|
||||
}
|
||||
mFormattingSDCard = DO_NOT_FORMAT_SDCARD_ANYMORE;
|
||||
mResetKeyHoldTime = data.mHoldTime;
|
||||
return EXECUTED;
|
||||
}
|
||||
bool TestMissionState::HoldUpResetKey(const KeyEventData &data)
|
||||
{
|
||||
mFormattingSDCard = SD_CARD_IS_NOT_FORMATTING;
|
||||
mResetKeyHoldTime = 0;
|
||||
return EXECUTED;
|
||||
}
|
||||
bool TestMissionState::HoldDownFormatKey(const KeyEventData &data)
|
||||
{
|
||||
constexpr int FORMAT_SD_CARD_PRESSING_TIME_MS = 1000 * 15;
|
||||
constexpr int MEANS_REALLY_HOLD_DOWN = 1000;
|
||||
if (FORMAT_SD_CARD_PRESSING_TIME_MS <= data.mHoldTime && SD_CARD_IS_NOT_FORMATTING == mFormattingSDCard) {
|
||||
LogInfo("format key down.\n");
|
||||
mFormattingSDCard = DO_NOT_FORMAT_SDCARD_ANYMORE;
|
||||
std::shared_ptr<VMissionData> message =
|
||||
std::make_shared<VMissionData>(static_cast<MissionEvent>(InternalStateEvent::FORMAT_KEY_FORMAT_SD_CARD));
|
||||
MissionStateMachine::GetInstance()->SendStateMessage(message);
|
||||
return EXECUTED;
|
||||
}
|
||||
if (MEANS_REALLY_HOLD_DOWN > data.mHoldTime) {
|
||||
return NOT_EXECUTED;
|
||||
}
|
||||
if (0 == mFormatKeyHoldTime) {
|
||||
constexpr int KEEP_MS = 1000 * 5;
|
||||
LedsHandle::ControlDeviceStatusLed(DeviceStatus::FORMAT_KEY_HOLD_DOWN_TIPS, KEEP_MS, LED_NOT_BLINK);
|
||||
}
|
||||
mFormatKeyHoldTime = data.mHoldTime;
|
||||
return NOT_EXECUTED;
|
||||
}
|
||||
bool TestMissionState::HoldUpFormatKey(const KeyEventData &data)
|
||||
{
|
||||
// mFormattingSDCard = false;
|
||||
mFormatKeyHoldTime = 0;
|
||||
return EXECUTED;
|
||||
}
|
||||
void inline TestMissionState::CloseWatchDog(void)
|
||||
{
|
||||
class McuAskCloseWatchDog : public McuAsk<ASK_RESULT>, public McuAskBase
|
||||
{
|
||||
public:
|
||||
McuAskCloseWatchDog() : McuAskBase(McuAskBlock::NOT_BLOCK, McuAskReply::NEED_REPLY)
|
||||
{
|
||||
} // using McuAskBlock::NOT_BLOCK
|
||||
virtual ~McuAskCloseWatchDog() = default;
|
||||
void ReplyFinished(const bool result) override
|
||||
{
|
||||
McuAskBase::ReplyFinished(result);
|
||||
if (result) {
|
||||
LogInfo("Ask data succeed, mDataReply = %d.\n", static_cast<int>(mDataReply));
|
||||
// Do something here.
|
||||
}
|
||||
else {
|
||||
LogError("Ask data falied.\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
std::shared_ptr<VMcuAsk> ask = std::make_shared<McuAskCloseWatchDog>();
|
||||
IMcuManager::GetInstance()->SetFeedingCycleForWatchDog(ask, CLOSE_WATCH_DOG);
|
||||
}
|
||||
SdCardStatus TestMissionState::SdCardStatusConvert(const StorageEvent &event)
|
||||
{
|
||||
switch (event) {
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "IStateMachine.h"
|
||||
#include "IStorageManager.h"
|
||||
#include "MissionState.h"
|
||||
constexpr bool DO_NOT_FORMAT_SDCARD_ANYMORE = true;
|
||||
constexpr bool SD_CARD_IS_NOT_FORMATTING = false;
|
||||
class TestMissionState : public MissionState, public AppMonitor
|
||||
{
|
||||
public:
|
||||
|
@ -30,8 +32,20 @@ private:
|
|||
bool SdCardEventReportSendToApp(VStateMachineData *msg);
|
||||
bool ResetKeyMediaTaskHandle(VStateMachineData *msg);
|
||||
bool ClickResetKey(const KeyEventData &data);
|
||||
bool HoldDownResetKey(const KeyEventData &data);
|
||||
bool HoldUpResetKey(const KeyEventData &data);
|
||||
bool HoldDownFormatKey(const KeyEventData &data);
|
||||
bool HoldUpFormatKey(const KeyEventData &data);
|
||||
|
||||
private:
|
||||
void CloseWatchDog(void);
|
||||
|
||||
private:
|
||||
SdCardStatus SdCardStatusConvert(const StorageEvent &event);
|
||||
|
||||
private:
|
||||
bool mFormattingSDCard;
|
||||
unsigned int mResetKeyHoldTime;
|
||||
unsigned int mFormatKeyHoldTime;
|
||||
};
|
||||
#endif
|
|
@ -13,14 +13,22 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "TopState.h"
|
||||
#include "DataProcessing.h"
|
||||
#include "IDeviceManager.h"
|
||||
#include "ILog.h"
|
||||
#include "IMcuManager.h"
|
||||
#include "IMediaManager.h"
|
||||
#include "IMissionManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "KeyControl.h"
|
||||
#include "McuMonitor.h"
|
||||
#include "MissionStateMachine.h"
|
||||
#include "StatusCode.h"
|
||||
#include <memory>
|
||||
TopState::TopState() : State("TopState")
|
||||
{
|
||||
mEventHandle[InternalStateEvent::STORAGE_HANDLE_STATE_INIT] =
|
||||
std::bind(&TopState::StorageStartInitHandle, this, _1);
|
||||
// mEventHandle[InternalStateEvent::STORAGE_HANDLE_STATE_INIT] =
|
||||
// std::bind(&TopState::StorageStartInitHandle, this, _1);
|
||||
}
|
||||
void TopState::GoInState()
|
||||
{
|
||||
|
@ -43,7 +51,7 @@ bool TopState::ExecuteStateMsg(VStateMachineData *msg)
|
|||
}
|
||||
StatusCode TopState::ReportEvent(const MediaReportEvent &event)
|
||||
{
|
||||
LogInfo(" ReportEvent:\n");
|
||||
LogInfo("Application recv media event(fast start).\n");
|
||||
std::shared_ptr<VMissionData> message = std::make_shared<VMissionDataV2<MediaReportEvent>>(
|
||||
static_cast<MissionEvent>(InternalStateEvent::MEDIA_REPORT_EVENT), event);
|
||||
MissionStateMachine::GetInstance()->SendStateMessage(message);
|
||||
|
@ -59,10 +67,4 @@ void TopState::KeyEventReport(const std::string &keyName, const VirtualKeyEvent
|
|||
std::shared_ptr<VMissionData> message = std::make_shared<VMissionDataV2<KeyEventData>>(
|
||||
static_cast<MissionEvent>(InternalStateEvent::KEY_EVENT_HANDLE), data);
|
||||
MissionStateMachine::GetInstance()->SendStateMessage(message);
|
||||
}
|
||||
bool TopState::StorageStartInitHandle(VStateMachineData *msg)
|
||||
{
|
||||
MissionStateMachine::GetInstance()->DelayMessage(msg);
|
||||
MissionStateMachine::GetInstance()->SwitchState(SystemState::STORAGE_HANDLE_STATE);
|
||||
return EXECUTED;
|
||||
}
|
|
@ -38,8 +38,5 @@ private: // About VMediaMonitor
|
|||
|
||||
private: // About KeyMonitor
|
||||
void KeyEventReport(const std::string &keyName, const VirtualKeyEvent &event, const unsigned int &timeMs) override;
|
||||
|
||||
private:
|
||||
bool StorageStartInitHandle(VStateMachineData *msg);
|
||||
};
|
||||
#endif
|
|
@ -13,10 +13,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "UpgradeState.h"
|
||||
#include "DataProcessing.h"
|
||||
#include "IHuntingUpgrade.h"
|
||||
#include "ILog.h"
|
||||
#include "IMediaManager.h"
|
||||
#include "IStateMachine.h"
|
||||
#include "MissionStateMachine.h"
|
||||
#include <functional>
|
||||
UpgradeState::UpgradeState() : State("UpgradeState")
|
||||
{
|
||||
mEventHandle[InternalStateEvent::CHECK_UPGRADE_FILE] = std::bind(&UpgradeState::CheckUpgradeFileHandle, this, _1);
|
||||
|
|
21
application/MissionManager/src/VStateBase.cpp
Normal file
21
application/MissionManager/src/VStateBase.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Fancy Code.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "VStateBase.h"
|
||||
void VStateBase::StateInit(void)
|
||||
{
|
||||
}
|
||||
void VStateBase::StateUnInit(void)
|
||||
{
|
||||
}
|
25
application/MissionManager/src/VStateBase.h
Normal file
25
application/MissionManager/src/VStateBase.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Fancy Code.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef V_STATE_BASE_H
|
||||
#define V_STATE_BASE_H
|
||||
class VStateBase
|
||||
{
|
||||
public:
|
||||
VStateBase() = default;
|
||||
virtual ~VStateBase() = default;
|
||||
virtual void StateInit(void);
|
||||
virtual void StateUnInit(void);
|
||||
};
|
||||
#endif
|
|
@ -35,7 +35,6 @@ if(${TEST_COVERAGE} MATCHES "true")
|
|||
target_link_libraries(${TARGET_NAME} gcov)
|
||||
endif()
|
||||
|
||||
if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true")
|
||||
add_custom_target(
|
||||
ipc_x86_code_check
|
||||
COMMAND ${CLANG_TIDY_EXE}
|
||||
|
@ -55,6 +54,7 @@ add_custom_target(
|
|||
-i ${SRC_FILES} ${HEADER_FILES} ${MAIN_SRC_FILE_THIS}
|
||||
WORKING_DIRECTORY ${APPLICATION_SOURCE_PATH}/main
|
||||
)
|
||||
if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true")
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
PRE_BUILD
|
||||
|
|
|
@ -48,7 +48,7 @@ set(LOG_SUPPORT "true")
|
|||
# ------------ build log end ------------ #
|
||||
|
||||
# ------------ build GoAhead ------------ #
|
||||
set(GOAHEAD_DOCUMENTS_PATH "web")
|
||||
set(GOAHEAD_DOCUMENTS_PATH "./sdcard") # web服务器配置文件的根目录,可以访问文件,例如:mp4,jpg,html等
|
||||
set(GOAHEAD_UPLOAD_TMP_PATH "./goahead")
|
||||
set(GOAHEAD_UPLOAD_PATH "${GOAHEAD_UPLOAD_TMP_PATH}")
|
||||
set(GOAHEAD_LIMIT_POST "335544320") # If not defined means using default setting. See goahead-linux-static-fancy.mk
|
||||
|
@ -86,4 +86,8 @@ set(APPLICATION_VERSION_1 1)
|
|||
set(APPLICATION_VERSION_2 0)
|
||||
set(APPLICATION_VERSION_3 0)
|
||||
set(APPLICATION_VERSION_4 0)
|
||||
# ------------ build upgrade end ------------ #
|
||||
# ------------ build upgrade end ------------ #
|
||||
|
||||
# ------------ build Gui ------------ #
|
||||
set(GUI_IMAGES_PATH "./gui_engine")
|
||||
# ------------ build Gui end ------------ #
|
|
@ -14,6 +14,9 @@ set(UTILS_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/utils")
|
|||
set(HAL_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/hal")
|
||||
set(TEST_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/test")
|
||||
set(EXTERNAL_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/external")
|
||||
# TODO: 这里设置CMAKE_INSTALL_PREFIX不是非常合理,
|
||||
# 由于CMAKE_INSTALL_PREFIX被莫名修改成其它值,在这里设置作为临时解决方案
|
||||
set(CMAKE_INSTALL_PREFIX "${PLATFORM_PATH}/${PROJECT_OUTPUT_FOLDER}")
|
||||
|
||||
# -------------------------- clang-tidy tools -------------------------- #
|
||||
set(CLANG_TIDY_CHECKS "-*,\
|
||||
|
@ -27,7 +30,7 @@ llvm-twine-local,\
|
|||
misc-confusable-identifiers,\
|
||||
misc-definitions-in-headers,\
|
||||
misc-header-include-cycle,\
|
||||
-misc-include-cleaner,\
|
||||
misc-include-cleaner,\
|
||||
misc-misleading-bidirectional,\
|
||||
misc-misleading-identifier,\
|
||||
misc-misplaced-const,\
|
||||
|
|
18
doc/boss_schedule.md
Normal file
18
doc/boss_schedule.md
Normal file
|
@ -0,0 +1,18 @@
|
|||
# 1. 开发规划与进度
|
||||
|
||||
  记录项目的规划与进度,以工程师为单位记录,负责人为工程师本人。
|
||||
|
||||
## 1.1. XIAO
|
||||
|
||||
```mermaid
|
||||
gantt
|
||||
dateFormat MM-DD
|
||||
title 工作规划与进度
|
||||
section 规划
|
||||
国科开发板 : crit, 2024-06-01,30d
|
||||
开发板 : active, 2024-08-01,60d
|
||||
海思平台确认 : active, 2024-07-15,30d
|
||||
section 实际进度
|
||||
未完成硬件工程师开发支持 : crit, active, 2024-06-01,15d
|
||||
国科平台缺料,无法打板 : crit, active, 2024-06-01,30d
|
||||
```
|
42
doc/clang-tidy_user_guide.md
Normal file
42
doc/clang-tidy_user_guide.md
Normal file
|
@ -0,0 +1,42 @@
|
|||
# 1. clang-tidy使用指南
|
||||
|
||||
   使用clang-tidy工具进行代码规范管理。
|
||||
1. 编译时实时报错;
|
||||
2. 指定自研源码检测;
|
||||
|
||||
## 1.1. 环境搭建
|
||||
|
||||
1. llvm使用cmake编译,cmake版本要求 3.20以上,此处使用cmake-3.27.4
|
||||
```
|
||||
// cmake源码目录://tools/cmake/cmake-3.27.4.tar.gz
|
||||
// cmake源码安装:
|
||||
tar zxvf cmake-3.27.4.tar.gz
|
||||
cd cmake-3.27.4/
|
||||
sudo apt-get install openssl // 如果执行./bootstrap提示缺少ssl相关资源,执行此安装命令
|
||||
./bootstrap
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
2. 安装llvm
|
||||
```
|
||||
// 下载源码
|
||||
git clone https://github.com/llvm/llvm-project.git
|
||||
cd llvm-project/
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD="X86" -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" ../llvm
|
||||
make -j8
|
||||
find ./ -name clang-tidy // 确认编译完成
|
||||
```
|
||||
|
||||
## 1.2. clang-tidy使用
|
||||
修改配置:< IPC-SDK >/build/global_config.cmake
|
||||
```
|
||||
# ------------ build clang-tools ------------ #
|
||||
if(${LINUX_TEST} MATCHES "true")
|
||||
set(CLANG_TIDY_SUPPORT "true") // 使能工具
|
||||
set(CLANG_FORMAT_SUPPORT "true")
|
||||
set(LLVM_PATH "/home/xiaojiazhu/project/tmp/llvm-project") // llvm安装目录
|
||||
endif()
|
||||
# ------------ build clang-tools end ------------ #
|
||||
```
|
54
doc/cmake_exploitReport.md
Normal file
54
doc/cmake_exploitReport.md
Normal file
|
@ -0,0 +1,54 @@
|
|||
# 1.cmake开发报告
|
||||
|
||||
## 1.1 前言
|
||||
该篇md用于ipc项目下log功能的cmakelist的开发报告,以阐述其功能和组成。
|
||||
|
||||
## 1.2 功能介绍
|
||||
* 设置库文件输出路径:`set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH})`.
|
||||
该语句用于设置该功能的静态库的生成路径,其中`${LIBS_OUTPUT_PATH}`在/build/cmake/global_config.cmake被定义在项目根目录的/output_files/libs/。
|
||||
|
||||
* 添加实现功能的文件目录:`include_directories(./)`.
|
||||
该语句旨在向编译器告知该功能的实现文件和头文件的所在位置。
|
||||
|
||||
* 添加功能目录到搜索路径:`set(CMAKE_AUTOMOC ON);set(CMAKE_INCLUDE_CURRENT_DIR ON)`
|
||||
这些 CMake 命令支持自动处理 Qt moc(元对象编译器),并将当前目录设置为包含在包含文件的搜索路径中;在构建过程中自动运行Qt moc编译器,用于包含Q_OBJECT宏的任何源文件。这对于为信号和插槽生成必要的C++代码是必需的;该选项将当前源目录添加到包含文件的搜索路径中。这允许构建系统查找与正在编译的源文件位于同一目录中的头文件。
|
||||
|
||||
* 收集、生成头文件列表:`file(GLOB_RECURSE HEADER_FILES "*.h")`
|
||||
该语句的功能是搜索当前目录及其子目录中扩展名为 .h 的所有文件。生成的文件列表存储在 HEADER_FILES 变量中。
|
||||
|
||||
* 收集源文件列表:`aux_source_directory(. SRC_FILES)`
|
||||
在本语句中,aux_source_directory(.SRC_FILES) 从当前目录(由 .) 及其子目录中收集所有源文件(例如,.cpp 个文件),生成的文件列表存储在 SRC_FILES 变量中。
|
||||
|
||||
* 添加编译器标志和定义到当前目录及其子目录:`add_definitions("-fexceptions")`
|
||||
添加编译器标志`-fexceptions`以在代码中启用异常处理。此标志告诉编译器生成支持捕获和引发异常的代码。通过使用 add_definitions(),可以将特定的编译器标志或定义全局应用于项目或特定源文件。
|
||||
|
||||
* 创建静态库目标:`add_library(xlog STATIC ${SRC_FILES} ${HEADER_FILES})`
|
||||
在这种情况下,本语句使用提供的源文件和头文件列表创建一个名为“xlog”的静态库目标;`STATIC`关键字指定库将构建为静态库,这意味着库代码将在编译时直接链接到最终可执行文件中;`${SRC_FILES}`变量包含应编译并链接到库中的源文件(通常.cpp文件)的列表。${HEADER_FILES} 变量包含头文件(通常为 .h 文件)的列表,这些文件定义库使用的接口和声明。
|
||||
|
||||
## 1.3 总结
|
||||
该篇cmakelists.txt的主要用途是对ipc项目下xlog功能的显现文件的编译和汇总。
|
||||
|
||||
## 2.1 返回码管理库概述
|
||||
提供整个应用程序的返回码管理功能,例如:打印返回码的字符串含义。提供C语言接口,内部实现不限于C或者C++,形成项目内部唯一返回码标准。
|
||||
|
||||
## 2.2 功能介绍
|
||||
* 设置可执行文件的输出路径:`set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH})`;`set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH})`
|
||||
|
||||
* 引入头文件目录:`include_directories`。`include_directories`表示引入头文件搜索路径,当工程要用到某个头文件的时候,就会去该路径下搜索。
|
||||
|
||||
* 开启自动编译:`set(CMAKE_AUTOMOC ON)` `set(CMAKE_INCLUDE_CURRENT_DIR ON)`. 这段代码开启了 CMake 的元对象编译器、界面编译器和资源编译器自动编译,这样当项目使用了包含元对象的文件、界面文件和资源文件时 CMake 可以自动检测并编译。
|
||||
|
||||
* 查找在./src路径下的所有源文件:`aux_source_directory(./src SRC_FILES)` 。
|
||||
|
||||
* 设置ReturnCode地址:`set(TARGET_NAME ReturnCode)`。根据提供的源文件创建一个叫ReturnCode的静态库。然后将目标文件与库文件进行链接:`target_link_libraries(${TARGET_NAME} Log)`。
|
||||
|
||||
## 2.3 返回码test
|
||||
* 添加test文件到目录,本目录为测试代码目录,目录结构保持与源码目录结构一致。
|
||||
|
||||
* 在test各个文件夹里添加相对应的CMakeLists.txt文件,通过`add_subdirectory(utils)`添加与源码目录结构相对应的子文件夹。
|
||||
|
||||
* 在src文件夹下创建ReturnCodeTest.cpp,调用返回码管理接口。在根目录添加第三方库文件,存放需要用到的第三方库。
|
||||
|
||||
## 2.4 总结
|
||||
Cmake的语句都在CMakeLists.txt的文件中,Cmake运行之后就会产生想要的makefile文件,然后再直接make就可以编译出可执行程序。
|
||||
|
299
doc/cmake_guide.md
Normal file
299
doc/cmake_guide.md
Normal file
|
@ -0,0 +1,299 @@
|
|||
# 1. CMake构建工具使用
|
||||
|
||||
  SDK使用CMake工具构建。
|
||||
|
||||
## 1.1. 安装
|
||||
|
||||
```code
|
||||
详见://tools/cmake/Makefile
|
||||
$ cd tools/cmake
|
||||
$ make
|
||||
$ cmake --version
|
||||
cmake version 3.27.4
|
||||
```
|
||||
|
||||
## 1.2. SDK构建配置脚本
|
||||
|
||||
* build目录下是基本的配置脚本。
|
||||
|
||||
```code
|
||||
build/
|
||||
├── cmake
|
||||
│ ├── Makefile // 调用cmake命令生成Makefile文件;
|
||||
│ └── toolchain
|
||||
│ └── linux.toolchain.cmake // 工具链配置文件已经一些全局变量;
|
||||
├── global_config.cmake // 配置文件
|
||||
└── sdk_config.cmake // 配置文件
|
||||
```
|
||||
|
||||
### 1.2.1. //build/cmake/Makefile
|
||||
|
||||
  调用cmake命令生成Makefile文件。
|
||||
|
||||
```code
|
||||
all:
|
||||
@mkdir -p ../../cmake-shell;\ // 创建cmake输出目录,这一步很关键,所有cmake的中间文件都将会存放在此目录。
|
||||
cd ../../cmake-shell;\
|
||||
pwd;\
|
||||
# 调用cmake命令,并指定工具链配置文件,生成Makefile文件。
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE="./build/cmake/toolchain/linux.toolchain.cmake" ..;\
|
||||
cd ..
|
||||
clean:
|
||||
rm -rf ../../cmake-shell
|
||||
```
|
||||
|
||||
在根目录执行:make cmake 的时候,即是调用上述Makefile生成Makefile文件。
|
||||
|
||||
### 1.2.2. //build/cmake/toolchain/linux.toolchain.cmake
|
||||
|
||||
  工具链配置文件或者一些跨平台差异化的配置文件。该文件在//build/cmake/Makefile中被指定,当需要交叉编译时,此文件的变量需要被重新配置。
|
||||
|
||||
```code
|
||||
|
||||
INCLUDE(CMakeForceCompiler)
|
||||
|
||||
set(LINUX_TEST "true")
|
||||
set(CROSS_COMPILE_PREFIX "") // 工具链前缀
|
||||
set(CMAKE_C_COMPILER "${CROSS_COMPILE_PREFIX}gcc") // 配置工具链
|
||||
set(CMAKE_CXX_COMPILER "${CROSS_COMPILE_PREFIX}g++") // 配置工具链
|
||||
|
||||
# path to compiler and utilities
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
|
||||
# Name of the target platform
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||
|
||||
# Version of the system
|
||||
set(CMAKE_SYSTEM_VERSION 1)
|
||||
cmake_policy(SET CMP0011 NEW)
|
||||
cmake_policy(SET CMP0005 NEW)
|
||||
|
||||
add_definitions(-Wall -O2 -Os)
|
||||
add_definitions(-Wno-unused-local-typedefs)
|
||||
add_definitions(-Wstrict-aliasing -Wwrite-strings)
|
||||
|
||||
set(TOOLCHAIN_NAME arm-linux-gnueabihf)
|
||||
|
||||
set(TARGET_PLATFORM "linux") // 编译系统平台,Linux表示在PC的ubuntu系统上编译
|
||||
set(SUBMODULE_PATH_OF_IPC_SDK "") // 子仓库路面,此处为空,交叉编译时设置
|
||||
set(PLATFORM_PATH "${CMAKE_CURRENT_SOURCE_DIR}") // 平台路径
|
||||
set(TEST_COVERAGE "true") // 覆盖率报告开关
|
||||
add_definitions(-DPLATFORM_PATH=\"${PLATFORM_PATH}\") // 定义一个宏
|
||||
set(PROJECT_OUTPUT_FOLDER "output_files") // 编译的目标文件输出目录
|
||||
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_OUTPUT_FOLDER}")
|
||||
|
||||
... // 此处省略不同模块的配置参数,一般是一些宏定义;
|
||||
```
|
||||
|
||||
### 1.2.3. //CMakeLists.txt
|
||||
|
||||
  SDK跟目录下的第一个CMakeLists.txt文件,cmake命令执行的时候会指定根目录,到此目录下寻找CMakeLists.txt文件作为整个项目的构建起点。
|
||||
|
||||
## 1.3. 重要的配置
|
||||
|
||||
### 1.3.1. 目录设置
|
||||
|
||||
  目录结构都是通过.cmake脚本来配置的。
|
||||
|
||||
#### 1.3.1.1. 源码目录结构配置
|
||||
|
||||
详见://build/global_config.cmake
|
||||
|
||||
```code
|
||||
set(EXEC_OUTPUT_PATH "${PLATFORM_PATH}/${PROJECT_OUTPUT_FOLDER}/bin")
|
||||
set(LIBS_OUTPUT_PATH "${PLATFORM_PATH}/${PROJECT_OUTPUT_FOLDER}/libs")
|
||||
set(TEST_TOOLS_OUTPUT_PATH "${PLATFORM_PATH}/${PROJECT_OUTPUT_FOLDER}/libs/test_tools")
|
||||
set(EXTERNAL_LIBS_OUTPUT_PATH "${PLATFORM_PATH}/${PROJECT_OUTPUT_FOLDER}/libs/external")
|
||||
set(TEST_OUTPUT_PATH "${PLATFORM_PATH}/${PROJECT_OUTPUT_FOLDER}/test")
|
||||
|
||||
set(PROJECT_ROOT_PATH "${PLATFORM_PATH}")
|
||||
set(APPLICATION_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/application") # 应用层目录
|
||||
set(MIDDLEWARE_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/middleware") # 中间件层目录
|
||||
set(UTILS_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/utils") # 工具层目录
|
||||
set(HAL_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/hal") # 硬件抽象层目录
|
||||
set(TEST_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/test") # 自动化测试代码/example目录
|
||||
set(EXTERNAL_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/external") # 外部依赖库目录
|
||||
```
|
||||
|
||||
## 1.4. CMakeLists.txt基本语法
|
||||
|
||||
### 1.4.1. 概述
|
||||
|
||||
  概括性描述就是,只需要告诉CMakeLists.txt文件,构建时包含哪些配置文件,依赖的头文件目录,需要编译的源码文件,依赖的目标目录(如有),输出的目标,依赖的目标(一般是库),CMakeLists.txt即可生成一个Makefile代码来构建这个目标。
|
||||
|
||||
  整个SDK由很多的CMakeLists.txt文件组成,绝大多数的CMakeLists.txt文件负责把该目录的源码编译成一个库,SDK通过链接不同功能的库来构建不同的应用程序。
|
||||
|
||||
```code
|
||||
./application/CMakeLists.txt
|
||||
./application/HuntingCamera/CMakeLists.txt
|
||||
./CMakeLists.txt
|
||||
./hal/CMakeLists.txt
|
||||
./middleware/AppManager/CMakeLists.txt
|
||||
./middleware/CMakeLists.txt
|
||||
./test/all/CMakeLists.txt
|
||||
./test/application/CMakeLists.txt
|
||||
./test/application/HuntingCamera/CMakeLists.txt
|
||||
./test/application/MissionManager/CMakeLists.txt
|
||||
./test/application/MissionManager/tool/CMakeLists.txt
|
||||
./test/application/VersionReleaseTool/CMakeLists.txt
|
||||
./test/CMakeLists.txt
|
||||
./test/hal/CMakeLists.txt
|
||||
./test/hal/tool/CMakeLists.txt
|
||||
./test/middleware/AppManager/CMakeLists.txt
|
||||
./tools/clang-tidy/CMakeLists.txt
|
||||
./utils/CMakeLists.txt
|
||||
./utils/Config/CMakeLists.txt
|
||||
./utils/ConfigBase/CMakeLists.txt
|
||||
```
|
||||
|
||||
### 1.4.2. 一个CMakeLists.txt示例
|
||||
|
||||
  CMakeLists.txt可以通过调用一些shell脚本来完成除编译之外的其它工具,例如:格式化代码。
|
||||
|
||||
```code
|
||||
|
||||
include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake)
|
||||
set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH}) // 设置可执行文件的输出目录
|
||||
set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH}) // 设置库文件的输出目录
|
||||
|
||||
include_directories( // 该目标需要依赖的头文件的目录
|
||||
./src
|
||||
./include
|
||||
${UTILS_SOURCE_PATH}/StatusCode/include
|
||||
${UTILS_SOURCE_PATH}/Log/include
|
||||
)
|
||||
|
||||
#do not rely on any other library
|
||||
#link_directories( // 该目标需要链接依赖的库的目录,因为是目标是库,无需链接,此设置无
|
||||
#)
|
||||
|
||||
aux_source_directory(./src SRC_FILES) // 需要编译的源码文件,此处是src目录下的所有文件
|
||||
|
||||
set(TARGET_NAME StatusCode) // 设置输出目标名称
|
||||
add_library(${TARGET_NAME} STATIC ${SRC_FILES})
|
||||
target_link_libraries(${TARGET_NAME} Log) // 该目标需要依赖的库,这一步很关键,cmake将会根据依赖关系自动去编译需要的依赖库;
|
||||
|
||||
if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true")
|
||||
add_custom_target( // 静态检测代码
|
||||
StatusCode_code_check
|
||||
COMMAND ${CLANG_TIDY_EXE}
|
||||
-checks='${CLANG_TIDY_CHECKS}'
|
||||
--header-filter=.*
|
||||
--system-headers=false
|
||||
${SRC_FILES}
|
||||
${CLANG_TIDY_CONFIG}
|
||||
-p ${PLATFORM_PATH}/cmake-shell
|
||||
WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/StatusCode
|
||||
)
|
||||
file(GLOB_RECURSE HEADER_FILES *.h)
|
||||
add_custom_target( // 格式化代码
|
||||
StatusCode_code_format
|
||||
COMMAND ${CLANG_FORMAT_EXE}
|
||||
-style=file
|
||||
-i ${SRC_FILES} ${HEADER_FILES}
|
||||
WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/StatusCode
|
||||
)
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
PRE_BUILD
|
||||
COMMAND make StatusCode_code_check
|
||||
COMMAND make StatusCode_code_format
|
||||
WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/
|
||||
)
|
||||
endif()
|
||||
|
||||
define_file_name(${TARGET_NAME}) // 该函数实现log库打印时,可打印文件名
|
||||
|
||||
file(GLOB_RECURSE INSTALL_HEADER_FILES include/*.h)
|
||||
install(FILES ${INSTALL_HEADER_FILES} DESTINATION include) // 拷贝头文件到安装目录
|
||||
```
|
||||
|
||||
### 1.4.3. 通过CMakeLists.txt构建开源库
|
||||
|
||||
  通过CMakeLists.txt构建开源库,可以自动关联第三方的依赖库,编译的时候自动按需编译对应的开源库。
|
||||
|
||||
```code
|
||||
|
||||
include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake)
|
||||
include(build/config_base.cmake)
|
||||
set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH})
|
||||
set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH})
|
||||
|
||||
include_directories(
|
||||
./src
|
||||
./include
|
||||
${UTILS_SOURCE_PATH}/StatusCode/include
|
||||
${UTILS_SOURCE_PATH}/Log/include
|
||||
${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib
|
||||
)
|
||||
# link_directories(
|
||||
# ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs
|
||||
# )
|
||||
|
||||
aux_source_directory(./src SRC_FILES)
|
||||
|
||||
set(TARGET_NAME ConfigBase)
|
||||
add_library(${TARGET_NAME} STATIC ${SRC_FILES})
|
||||
target_link_libraries(${TARGET_NAME} StatusCode Log libconfig.a)
|
||||
|
||||
if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true")
|
||||
add_custom_target(
|
||||
ConfigBase_code_check
|
||||
COMMAND ${CLANG_TIDY_EXE}
|
||||
-checks='${CLANG_TIDY_CHECKS}'
|
||||
--header-filter=.*
|
||||
--system-headers=false
|
||||
${SRC_FILES}
|
||||
${CLANG_TIDY_CONFIG}
|
||||
-p ${PLATFORM_PATH}/cmake-shell
|
||||
WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/ConfigBase
|
||||
)
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
PRE_BUILD
|
||||
COMMAND make ConfigBase_code_check
|
||||
WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/
|
||||
)
|
||||
file(GLOB_RECURSE HEADER_FILES *.h)
|
||||
add_custom_target(
|
||||
ConfigBase_code_format
|
||||
COMMAND ${CLANG_FORMAT_EXE}
|
||||
-style=file
|
||||
-i ${SRC_FILES} ${HEADER_FILES}
|
||||
WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/ConfigBase
|
||||
)
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
PRE_BUILD
|
||||
COMMAND make ConfigBase_code_check
|
||||
COMMAND make ConfigBase_code_format
|
||||
WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/
|
||||
)
|
||||
endif()
|
||||
|
||||
# build libconfig before make libConfigBase.a
|
||||
add_custom_command(
|
||||
# OUTPUT ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs/libconfig.a
|
||||
OUTPUT ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig.a // 创建这个开源库输出文件的生成方法
|
||||
COMMAND echo "Build libconfig-1.7.3. COMPILE_HOST = ${COMPILE_HOST}"
|
||||
# COMMAND tar zxvf libconfig-1.7.3.tar.gz
|
||||
COMMAND sh build_libconfig.sh ${TARGET_PLATFORM} ${COMPILE_HOST}
|
||||
# 把生成的开源库拷贝到输出目录
|
||||
COMMAND mv ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs/libconfig.a ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig.a
|
||||
WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/libconfig/
|
||||
)
|
||||
add_custom_target(
|
||||
libconfig.a // 创建一个库目标
|
||||
# DEPENDS ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs/libconfig.a
|
||||
DEPENDS ${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig.a // 这个目标依赖开源库的编译输出文件
|
||||
)
|
||||
|
||||
define_file_name(${TARGET_NAME})
|
||||
config_owner(${TARGET_NAME})
|
||||
|
||||
file(GLOB_RECURSE INSTALL_HEADER_FILES include/*.h)
|
||||
install(FILES ${INSTALL_HEADER_FILES} DESTINATION include)
|
||||
```
|
1103
doc/design.md
Normal file
1103
doc/design.md
Normal file
File diff suppressed because it is too large
Load Diff
111
doc/develop_standard.md
Normal file
111
doc/develop_standard.md
Normal file
|
@ -0,0 +1,111 @@
|
|||
# 1. SDK开发规范
|
||||
|
||||
## 1.1. 编码规范
|
||||
|
||||
### 1.1.1. 指针/智能指针
|
||||
|
||||
* C++编码只能使用智能指针;
|
||||
* 指针遵循谁使用谁进行“非空”判断,且无比使用前进行“非空”判断;
|
||||
* 智能指针经过转换后务必进行“非空”判断;
|
||||
|
||||
理论上,**明显不可能为空的指针,可以不进行“非空”判断**,可以不进行“非空”判断的场景:
|
||||
|
||||
```
|
||||
void McuManagerImpl::OtherSideSendIpcMission(const unsigned int &serialNumber, const unsigned char &mission)
|
||||
{
|
||||
class McuRecvIpcMission : public McuRecvImpl, public McuRecv<unsigned char>
|
||||
{
|
||||
public:
|
||||
McuRecvIpcMission(std::shared_ptr<McuManagerImpl> &mcuManager, const unsigned int &serialNumber,
|
||||
const OtherSideSendType &sendType, const unsigned char &mission)
|
||||
: McuRecvImpl(serialNumber, sendType)
|
||||
{
|
||||
McuRecv::mDataRecvReply = mission;
|
||||
McuRecvImpl::mMcuManager = mcuManager;
|
||||
}
|
||||
~McuRecvIpcMission() = default;
|
||||
void ReplyFinished(const bool result) override
|
||||
{
|
||||
// 此处可以不进行“非空”判断,该值在有限范围内(OtherSideSendIpcMission函数内部)就能看出是否为空
|
||||
McuRecvImpl::mMcuManager->ReplyOtherSideSendIpcMission(ASK_RESULT::SUCCEED, McuRecvImpl::mSerialNumber);
|
||||
}
|
||||
};
|
||||
std::shared_ptr<VMcuMonitor> monitor = GetMcuMonitor();
|
||||
std::shared_ptr<McuManagerImpl> manager = std::dynamic_pointer_cast<McuManagerImpl>(SharedFromThis());
|
||||
std::shared_ptr<VMcuRecv> recv =
|
||||
std::make_shared<McuRecvIpcMission>(manager, serialNumber, OtherSideSendType::SEND_IPC_MISSION, mission);
|
||||
if (monitor) {
|
||||
monitor->RecvIpcMissionEvent(recv, static_cast<IpcMission>(mission));
|
||||
}
|
||||
else {
|
||||
LogWarning("mMonitor is nullptr, AddMcuRecv.\n");
|
||||
AddMcuRecv(recv);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**没有进行“非空”判断的代码,应该开发测试用例,保证“空指针”的报错。**
|
||||
|
||||
### 1.1.2. 注释
|
||||
|
||||
* 注释必须使用英文,且使用翻译器翻译;
|
||||
  避免编码问题导致的乱码,且需要保证阅读困难时可使用翻译器翻译成可读的中文;
|
||||
|
||||
**注:** 注释翻译工具使用[百度翻译](https://fanyi.baidu.com/);翻译的注释在使用doxygen工具生成接口文档时,在网页上方便翻译成中文。
|
||||
|
||||
### 1.1.3. C++继承
|
||||
|
||||
* 子类使用父类的函数时,函数前必须加父类名,降低阅读难度,没有父类名的一律为本类函数(有可能是虚函数);
|
||||
|
||||
### 1.1.4. 变量命名
|
||||
|
||||
#### 1.1.4.1. 结构体/类成员
|
||||
|
||||
* 结构体和类成员必须要使用驼峰命名法,且首字母必须为m表示成员变量;
|
||||
|
||||
```
|
||||
typedef struct app_get_product_info
|
||||
{
|
||||
app_get_product_info();
|
||||
std::string mModel;
|
||||
std::string mCompany;
|
||||
std::string mSoc;
|
||||
std::string mSp;
|
||||
} AppGetProductInfo;
|
||||
```
|
||||
|
||||
### 1.1.5. 文件命名
|
||||
|
||||
* 文件名必须使用驼峰命名法,且首字母大写;
|
||||
|
||||
### 1.1.6. 代码排版
|
||||
|
||||
* 使用统一标准的代码排版风格,保持多人开发时代码的整洁,避免因为排版(特别是编辑工具的自动排版功能)导致每次提交时都产生大量的排版修改,影响后续代码异常排查;
|
||||
|
||||
  请使用仓库跟目录下.clang-format配置文件进行排版,如果使用vscode编辑器开发代码,可直接使用快捷键ctrl+alt+f进行排版;也可以使用构建脚本对代码进行排版。
|
||||
|
||||
**对发生修改的代码进行格式化:**
|
||||
|
||||
```code
|
||||
$ make cmake // 在仓库根目录执行,对发生修改的文件创建格式化命令
|
||||
$ cd cmake-shell/
|
||||
$ make improve_modified_code // 文件格式化命令,统一排版,此命名只对发生修改的文件进行格式化
|
||||
```
|
||||
|
||||
**对全部文件进行格式化:**
|
||||
|
||||
```code
|
||||
详见配置文件://build/global_config.cmake
|
||||
把 COMPILE_IMPROVE_SUPPORT 设置为 true 时,将会在每次编译代码时进行格式化。
|
||||
if(${LINUX_TEST} MATCHES "true")
|
||||
set(CLANG_TIDY_SUPPORT "true")
|
||||
set(CLANG_FORMAT_SUPPORT "true")
|
||||
set(COMPILE_IMPROVE_SUPPORT "false") # 开启后每次编译可能会很慢
|
||||
set(LLVM_PATH "$ENV{HOME}/llvm-project")
|
||||
endif()
|
||||
```
|
||||
|
||||
### 1.1.7. 函数
|
||||
|
||||
* 单个函数代码行控制在50行内,阅读时无需上下滚动去理解代码逻辑;极少数初始化数据的无逻辑推理的代码除外;
|
||||
* 函数参数不能超过10个;
|
21
doc/doxygen_user_guide.md
Normal file
21
doc/doxygen_user_guide.md
Normal file
|
@ -0,0 +1,21 @@
|
|||
# 1. Linux嵌入式项目使用Doxygen生成API文档
|
||||
|
||||
## 1.1. Doxygen简介
|
||||
|
||||
  Doxygen是一个开源的文档生成工具,可以用来生成项目源代码的API文档。
|
||||
|
||||
## 1.2. Doxygen安装
|
||||
|
||||
  Doxygen安装非常简单,直接在官网下载最新版本即可。
|
||||
|
||||
```
|
||||
$ sudo apt-get install doxygen
|
||||
```
|
||||
|
||||
## 1.3. 安装Graphviz
|
||||
|
||||
  Doxygen本身不直接支持画图功能,但它可以生成DOT格式的图形描述文件,然后使用Graphviz工具进行渲染。
|
||||
|
||||
```
|
||||
$ sudo apt-get install graphviz
|
||||
```
|
210
doc/gdb_coredump_guide.md
Normal file
210
doc/gdb_coredump_guide.md
Normal file
|
@ -0,0 +1,210 @@
|
|||
# 1. gdb coredump分析
|
||||
|
||||
  本文介绍ubuntu系统环境下coredump文件的分析方法。**重要:此文的场景在Ubuntu每次开机后需要重复设置coredump调试环境,例如开启coredump和设置coredump文件生成路径。**
|
||||
|
||||
**一个coredump示例:**
|
||||
|
||||
```code
|
||||
$ ../output_files/test/bin/McuManagerTest --gtest_filter=McuManagerTest.RH_INTEGRATION_McuManager_AUTO_OtherSideSendIpcMission
|
||||
Note: Google Test filter = McuManagerTest.RH_INTEGRATION_McuManager_AUTO_OtherSideSendIpcMission
|
||||
[==========] Running 1 test from 1 test suite.
|
||||
[----------] Global test environment set-up.
|
||||
[----------] 1 test from McuManagerTest
|
||||
NewLog succeed.
|
||||
LogImplInit
|
||||
[ RUN ] McuManagerTest.RH_INTEGRATION_McuManager_AUTO_OtherSideSendIpcMission
|
||||
2024-05-15 17:43:04,782 INFO [default] [McuManagerMakePtr.cpp:23]:CreateMcuManager is ok.
|
||||
|
||||
2024-05-15 17:43:04,783 INFO [default] [IMcuManager.cpp:72]:Instance changed succeed.
|
||||
|
||||
2024-05-15 17:43:04,783 INFO [default] [UartDeviceImpl.cpp:277]:Create the uart device object.
|
||||
|
||||
Can't Open Serial Port: No such file or directory
|
||||
2024-05-15 17:43:04,784 ERROR [default] [McuDevice.cpp:51]:IUartOpen failed.
|
||||
|
||||
2024-05-15 17:43:04,787 INFO [default] [UartDeviceImpl.cpp:277]:Create the uart device object.
|
||||
|
||||
Can't Open Serial Port: No such file or directory
|
||||
2024-05-15 17:43:04,787 ERROR [default] [McuDevice.cpp:51]:IUartOpen failed.
|
||||
|
||||
terminate called without an active exception
|
||||
Aborted (core dumped)
|
||||
```
|
||||
|
||||
## 1.1. coredump文件生成路径查询
|
||||
|
||||
```code
|
||||
$ cat /proc/sys/kernel/core_pattern
|
||||
|/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E
|
||||
```
|
||||
|
||||
修改coredump文件生成路径:
|
||||
|
||||
```code
|
||||
$ sudo sh -c 'echo /home/xiaojiazhu/project/ipc-sdk/ipc/cmake-shell/core.%e.%p > /proc/sys/kernel/core_pattern'
|
||||
$ cat /proc/sys/kernel/core_pattern
|
||||
/home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/cmake-shell/core.%e.%p
|
||||
```
|
||||
|
||||
命令:
|
||||
sudo sh -c 'echo /path/core.%e.%p > /proc/sys/kernel/core_pattern'
|
||||
|
||||
例如(根据自己的实际情况写路径参数):
|
||||
|
||||
```code
|
||||
sudo sh -c 'echo /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/cmake-shell/core.%e.%p > /proc/sys/kernel/core_pattern'
|
||||
```
|
||||
|
||||
**发现路径下并未生成coredump文件**
|
||||
|
||||
```code
|
||||
$ ulimit -a
|
||||
core file size (blocks, -c) 0 // 0表示终端未开启core dump
|
||||
data seg size (kbytes, -d) unlimited
|
||||
scheduling priority (-e) 0
|
||||
file size (blocks, -f) unlimited
|
||||
pending signals (-i) 63499
|
||||
max locked memory (kbytes, -l) 65536
|
||||
max memory size (kbytes, -m) unlimited
|
||||
open files (-n) 1024
|
||||
pipe size (512 bytes, -p) 8
|
||||
POSIX message queues (bytes, -q) 819200
|
||||
real-time priority (-r) 0
|
||||
stack size (kbytes, -s) 8192
|
||||
cpu time (seconds, -t) unlimited
|
||||
max user processes (-u) 63499
|
||||
virtual memory (kbytes, -v) unlimited
|
||||
file locks (-x) unlimited
|
||||
```
|
||||
|
||||
解决:
|
||||
|
||||
```code
|
||||
$ ulimit -c unlimited
|
||||
```
|
||||
|
||||
## 1.2. gdb查看堆栈信息
|
||||
|
||||
**Ubuntu系统需要加sudo执行程序才会生成coredump文件。**
|
||||
|
||||
### 1.2.1. 无法识别coredump文件
|
||||
|
||||
  在gdb中无法识别coredump文件,如下所示:
|
||||
|
||||
```code
|
||||
$ sudo gdb ../output_files/test/bin/McuManagerTest core.smbd.3390383
|
||||
[sudo] password for xiaojiazhu:
|
||||
Sorry, try again.
|
||||
[sudo] password for xiaojiazhu:
|
||||
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
||||
This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law.
|
||||
Type "show copying" and "show warranty" for details.
|
||||
This GDB was configured as "x86_64-linux-gnu".
|
||||
Type "show configuration" for configuration details.
|
||||
For bug reporting instructions, please see:
|
||||
<http://www.gnu.org/software/gdb/bugs/>.
|
||||
Find the GDB manual and other documentation resources online at:
|
||||
<http://www.gnu.org/software/gdb/documentation/>.
|
||||
|
||||
For help, type "help".
|
||||
Type "apropos word" to search for commands related to "word"...
|
||||
Reading symbols from ../output_files/test/bin/McuManagerTest...
|
||||
|
||||
warning: core file may not match specified executable file. // 表示coredump文件与可执行文件不匹配
|
||||
[New LWP 3390383]
|
||||
Core was generated by `/usr/sbin/smbd --foreground --no-process-group'.
|
||||
Program terminated with signal SIGABRT, Aborted.
|
||||
#0 0x00007fd59718600b in ?? ()
|
||||
(gdb) bt
|
||||
#0 0x00007fd59718600b in ?? ()
|
||||
#1 0x0000000000001c80 in ?? ()
|
||||
#2 0x0000000000000000 in ?? ()
|
||||
```
|
||||
|
||||
**由于gdb和asan同时启用会冲突,导致无法识别coredump文件。解决办法如下:**
|
||||
|
||||
修改://build/sdk_config.cmake
|
||||
|
||||
```code
|
||||
# Gdb debug
|
||||
if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX})
|
||||
message("---------------------------Debug mode.-----------------------")
|
||||
SET(CMAKE_BUILD_TYPE "Debug")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -Wall -g -ggdb")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -Wall -g -ggdb")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
|
||||
# asan
|
||||
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=leak -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined")
|
||||
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=leak -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined")
|
||||
else()
|
||||
message("---------------------------Release mode.-----------------------")
|
||||
SET(CMAKE_BUILD_TYPE "Release")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Os")
|
||||
endif()
|
||||
```
|
||||
|
||||
解决后:
|
||||
|
||||
```code
|
||||
$ sudo gdb ../output_files/test/bin/McuManagerTest core.McuManagerTest.3406751
|
||||
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
||||
This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law.
|
||||
Type "show copying" and "show warranty" for details.
|
||||
This GDB was configured as "x86_64-linux-gnu".
|
||||
Type "show configuration" for configuration details.
|
||||
For bug reporting instructions, please see:
|
||||
<http://www.gnu.org/software/gdb/bugs/>.
|
||||
Find the GDB manual and other documentation resources online at:
|
||||
<http://www.gnu.org/software/gdb/documentation/>.
|
||||
|
||||
For help, type "help".
|
||||
Type "apropos word" to search for commands related to "word"...
|
||||
Reading symbols from ../output_files/test/bin/McuManagerTest...
|
||||
[New LWP 3406751]
|
||||
[New LWP 3406753]
|
||||
[New LWP 3406752]
|
||||
[Thread debugging using libthread_db enabled]
|
||||
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
|
||||
Core was generated by `../output_files/test/bin/McuManagerTest --gtest_filter=McuManagerTest.RH_INTEGR'.
|
||||
Program terminated with signal SIGABRT, Aborted.
|
||||
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
|
||||
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
|
||||
[Current thread is 1 (Thread 0x7fd355968740 (LWP 3406751))]
|
||||
(gdb) bt
|
||||
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
|
||||
#1 0x00007fd35598f859 in __GI_abort () at abort.c:79
|
||||
#2 0x00007fd355d678d1 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
|
||||
#3 0x00007fd355d7337c in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
|
||||
#4 0x00007fd355d733e7 in std::terminate() () from /lib/x86_64-linux-gnu/libstdc++.so.6
|
||||
#5 0x000055c247b3ae41 in std::thread::operator= (__t=..., this=0x55c248d19748) at /usr/include/c++/9/thread:152
|
||||
#6 McuProtocol::Init (this=this@entry=0x55c248d196f8) at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/utils/McuProtocol/src/McuProtocol.cpp:58
|
||||
#7 0x000055c247b03e57 in McuManagerImpl::Init (this=0x55c248d19680)
|
||||
at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/middleware/McuManager/src/McuManagerImpl.cpp:46
|
||||
#8 0x000055c247acd3d4 in McuManagerTest::McuManagerTest_RH_INTEGRATION_McuManager_AUTO_OtherSideSendIpcMission_Test::TestBody (this=<optimized out>)
|
||||
at /usr/include/c++/9/bits/shared_ptr_base.h:1020
|
||||
#9 0x000055c247b303fd in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) () at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/utils/McuProtocol/./include/McuProtocol.h:121
|
||||
#10 0x000055c247b23343 in testing::Test::Run() () at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/utils/McuProtocol/./include/McuProtocol.h:121
|
||||
#11 0x000055c247b2342b in testing::TestInfo::Run() ()
|
||||
at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/utils/McuProtocol/./include/McuProtocol.h:121
|
||||
#12 0x000055c247b2376e in testing::TestSuite::Run() ()
|
||||
at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/utils/McuProtocol/./include/McuProtocol.h:121
|
||||
#13 0x000055c247b2a0fa in testing::internal::UnitTestImpl::RunAllTests() ()
|
||||
at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/utils/McuProtocol/./include/McuProtocol.h:121
|
||||
#14 0x000055c247b3085e in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) ()
|
||||
at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/utils/McuProtocol/./include/McuProtocol.h:121
|
||||
#15 0x000055c247b23529 in testing::UnitTest::Run() ()
|
||||
at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/utils/McuProtocol/./include/McuProtocol.h:121
|
||||
#16 0x000055c247ac9287 in RUN_ALL_TESTS ()
|
||||
at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/external/gtest/googletest-release-1.11.0/googletest/include/gtest/gtest.h:2490
|
||||
#17 main (argc=<optimized out>, argv=<optimized out>)
|
||||
at /home/xiaojiazhu/project/rkipc/battery/ipc-rk1106/ipc-sdk/test/middleware/McuManager/mainTest.cpp:22
|
||||
(gdb)
|
||||
```
|
267
doc/git_guide.md
Normal file
267
doc/git_guide.md
Normal file
|
@ -0,0 +1,267 @@
|
|||
# 1. git使用手册
|
||||
|
||||
## 1.1. 概述
|
||||
|
||||
  git是分布式版本控制系统,在多人开发中,git可以很好的管理代码的版本。
|
||||
|
||||
## 1.2. 源码托管服务器
|
||||
|
||||
  github和gitlab还有gitee(国产)都是开源的代码托管服务器,可以用来管理源码。
|
||||
|
||||
## 1.3. git安装
|
||||
|
||||
## 1.4. git分支管理
|
||||
|
||||
### 1.4.1. git创建本地分支
|
||||
|
||||
* 基于远端分支创建一个本地分支,同时新建一个对应的远端分支:
|
||||
|
||||
  当主干发生较大变化,例如:原厂更新sdk时,需要新建分支,划分界限。
|
||||
|
||||
```code
|
||||
$ git branch -a
|
||||
----------------
|
||||
* master
|
||||
remotes/origin/HEAD -> origin/master
|
||||
remotes/origin/app_test
|
||||
remotes/origin/master
|
||||
$ git checkout -b master-sdk-202405 origin/master
|
||||
-------------------------------------------------
|
||||
M ipc-sdk
|
||||
Branch 'master-sdk-202405' set up to track remote branch 'master' from 'origin'.
|
||||
Switched to a new branch 'master-sdk-202405'
|
||||
$ git branch -a
|
||||
----------------
|
||||
master
|
||||
* master-sdk-202405
|
||||
remotes/origin/HEAD -> origin/master
|
||||
remotes/origin/app_test
|
||||
remotes/origin/master
|
||||
$ git push origin master-sdk-202405:sdk-202405
|
||||
----------------------------------------------
|
||||
Enumerating objects: 3, done.
|
||||
Counting objects: 100% (3/3), done.
|
||||
Delta compression using up to 8 threads
|
||||
Compressing objects: 100% (2/2), done.
|
||||
Writing objects: 100% (2/2), 250 bytes | 250.00 KiB/s, done.
|
||||
Total 2 (delta 1), reused 0 (delta 0)
|
||||
remote: Powered by GITEE.COM [GNK-6.4]
|
||||
remote: Create a pull request for 'sdk-202405' on Gitee by visiting:
|
||||
remote: https://gitee.com/shenzhen-jiuyilian/ipc-rk1106/pull/new/shenzhen-jiuyilian:sdk-202405...shenzhen-jiuyilian:master
|
||||
To gitee.com:shenzhen-jiuyilian/ipc-rk1106.git
|
||||
* [new branch] master-sdk-202405 -> sdk-202405
|
||||
$ git branch -a
|
||||
---------------
|
||||
master
|
||||
* master-sdk-202405
|
||||
remotes/origin/HEAD -> origin/master
|
||||
remotes/origin/app_test
|
||||
remotes/origin/master
|
||||
remotes/origin/sdk-202405
|
||||
```
|
||||
|
||||
### 1.4.2. git获取远端分支
|
||||
|
||||
  当想知道远端是否新建了分支,可使用git fetch命令获取远端分支。
|
||||
|
||||
**git fetch示例:**
|
||||
|
||||
```code
|
||||
$ git fetch
|
||||
------------
|
||||
remote: Enumerating objects: 21, done.
|
||||
remote: Counting objects: 100% (21/21), done.
|
||||
remote: Compressing objects: 100% (11/11), done.
|
||||
remote: Total 14 (delta 8), reused 0 (delta 0), pack-reused 0
|
||||
Unpacking objects: 100% (14/14), 2.14 KiB | 156.00 KiB/s, done.
|
||||
From gitee.com:shenzhen-jiuyilian/ipc-rk1106
|
||||
bf71a01..2b9b803 master -> origin/master
|
||||
* [new branch] sdk-202402 -> origin/sdk-202402 // 此处发现远端新建了分支
|
||||
Fetching submodule ipc-sdk
|
||||
From gitee.com:shenzhen-jiuyilian/ipc
|
||||
7c261bd..eec9fb4 master-develop -> origin/master-develop
|
||||
```
|
||||
|
||||
**多个远端仓库git fetch示例:**
|
||||
|
||||
```code
|
||||
$ git remote -v
|
||||
----------------
|
||||
dgiot git@gitee.com:shenzhen-jiuyilian/fastbootserver.git (fetch)
|
||||
dgiot git@gitee.com:shenzhen-jiuyilian/fastbootserver.git (push)
|
||||
rk https://gerrit.rock-chips.com:8443/linux/linux/ipc/app/fastboot_server (fetch)
|
||||
rk https://gerrit.rock-chips.com:8443/linux/linux/ipc/app/fastboot_server (push)
|
||||
$ git fetch dgiot // git fetch + 远端仓库名称
|
||||
---------------------------------------------
|
||||
remote: Enumerating objects: 9, done.
|
||||
remote: Counting objects: 100% (9/9), done.
|
||||
remote: Compressing objects: 100% (7/7), done.
|
||||
remote: Total 9 (delta 3), reused 5 (delta 2), pack-reused 0
|
||||
Unpacking objects: 100% (9/9), 8.74 KiB | 746.00 KiB/s, done.
|
||||
From gitee.com:shenzhen-jiuyilian/fastbootserver
|
||||
* [new branch] sdk-202405 -> dgiot/sdk-202405
|
||||
```
|
||||
|
||||
### 1.4.3. git新增远端地址
|
||||
|
||||
  在一个git仓库中,可以同时管理多个远端地址,例如:在原厂的git仓库中,可以在仓库添加一个私人的git仓库,这样后续把修改提交到自己的仓库进行代码管理。
|
||||
|
||||
**git remote add示例:**
|
||||
|
||||
命令格式:
|
||||
|
||||
```code
|
||||
git remote add <remote-name> <remote-url>
|
||||
```
|
||||
|
||||
示例:
|
||||
|
||||
```code
|
||||
$ git remote add dgiot git@gitee.com:shenzhen-jiuyilian/fastbootserver.git
|
||||
---------------------------------------------------------------------------
|
||||
$ git remote -v
|
||||
----------------
|
||||
dgiot git@gitee.com:shenzhen-jiuyilian/fastbootserver.git (fetch)
|
||||
dgiot git@gitee.com:shenzhen-jiuyilian/fastbootserver.git (push)
|
||||
rk https://gerrit.rock-chips.com:8443/linux/linux/ipc/app/fastboot_server (fetch)
|
||||
rk https://gerrit.rock-chips.com:8443/linux/linux/ipc/app/fastboot_server (push)
|
||||
$ git fetch dgiot
|
||||
------------------
|
||||
remote: Enumerating objects: 107, done.
|
||||
remote: Counting objects: 100% (104/104), done.
|
||||
remote: Compressing objects: 100% (45/45), done.
|
||||
remote: Total 99 (delta 47), reused 89 (delta 42), pack-reused 0
|
||||
Unpacking objects: 100% (99/99), 29.55 KiB | 315.00 KiB/s, done.
|
||||
From gitee.com:shenzhen-jiuyilian/fastbootserver
|
||||
* [new branch] master -> dgiot/master
|
||||
* [new branch] sdk-202405 -> dgiot/sdk-202405
|
||||
$ git branch -a
|
||||
----------------
|
||||
* (HEAD detached at bf91101)
|
||||
remotes/dgiot/master
|
||||
remotes/dgiot/sdk-202405
|
||||
remotes/m/master
|
||||
remotes/rk/master
|
||||
$ git checkout -b sdk-202405 m/master
|
||||
--------------------------------------
|
||||
Switched to a new branch 'sdk-202405'
|
||||
$ git branch -a
|
||||
----------------
|
||||
* sdk-202405
|
||||
remotes/dgiot/master
|
||||
remotes/dgiot/sdk-202405
|
||||
remotes/m/master
|
||||
remotes/rk/master
|
||||
$ git pull dgiot sdk-202405
|
||||
---------------------------
|
||||
From gitee.com:shenzhen-jiuyilian/fastbootserver
|
||||
* branch sdk-202405 -> FETCH_HEAD
|
||||
Updating bf91101..dc76264
|
||||
Fast-forward
|
||||
.clang-format | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
.gitmodules | 3 +++
|
||||
README.md | 30 ++++++++++++++++++++++++++++++
|
||||
rv1106_ipc_sdk | 1 +
|
||||
4 files changed, 170 insertions(+)
|
||||
create mode 100644 .clang-format
|
||||
create mode 100644 .gitmodules
|
||||
create mode 100755 README.md
|
||||
create mode 160000 rv1106_ipc_sdk
|
||||
$ git submodule update --init
|
||||
-----------------------------
|
||||
Submodule 'rv1106_ipc_sdk' (git@gitee.com:shenzhen-jiuyilian/ipc-rk1106.git) registered for path 'rv1106_ipc_sdk'
|
||||
Cloning into '/home/xiaojiazhu/project/rkipc/ipc_20240517/project/app/component/fastboot_server/rv1106_ipc_sdk'...
|
||||
Submodule path 'rv1106_ipc_sdk': checked out 'ff8da760b201d365300aed78190de8564f0d2171'
|
||||
```
|
||||
|
||||
### 1.4.4. git删除远端地址
|
||||
|
||||
```code
|
||||
# git remote remove <remote-name>
|
||||
$ git remote -v
|
||||
---------------
|
||||
Germany payton@git.affgt.com:Germany/hunting.git (fetch)
|
||||
Germany payton@git.affgt.com:Germany/hunting.git (push)
|
||||
origin git@gitee.com:shenzhen-jiuyilian/ipc.git (fetch)
|
||||
origin git@gitee.com:shenzhen-jiuyilian/ipc.git (push)
|
||||
$ git remote remove Germany
|
||||
---------------------------
|
||||
$ git remote -v
|
||||
----------------
|
||||
origin git@gitee.com:shenzhen-jiuyilian/ipc.git (fetch)
|
||||
origin git@gitee.com:shenzhen-jiuyilian/ipc.git (push)
|
||||
```
|
||||
|
||||
### 1.4.5. git删除远端分支
|
||||
|
||||
```code
|
||||
# git push <remote-name> --delete <branch-name>
|
||||
$ git branch -r
|
||||
---------------
|
||||
origin/Branch_QT
|
||||
origin/HEAD -> origin/master
|
||||
origin/master
|
||||
origin/master-develop
|
||||
origin/without-testtools
|
||||
$ git push origin --delete Branch_QT
|
||||
-------------------------------------
|
||||
remote: Powered by GITEE.COM [GNK-6.4]
|
||||
To gitee.com:shenzhen-jiuyilian/ipc.git
|
||||
- [deleted] Branch_QT
|
||||
```
|
||||
|
||||
### 1.4.6. git删除本地分支
|
||||
|
||||
```code
|
||||
# git branch -d <branch-name>
|
||||
$ git branch -a
|
||||
----------------
|
||||
=-a
|
||||
master
|
||||
* sdk-202405
|
||||
remotes/origin/HEAD -> origin/master
|
||||
remotes/origin/app_test
|
||||
remotes/origin/master
|
||||
remotes/origin/sdk-202402
|
||||
remotes/origin/sdk-202405
|
||||
$ git branch -d =-a
|
||||
--------------------
|
||||
Deleted branch =-a (was c29b4f5).
|
||||
$ git branch -a
|
||||
---------------
|
||||
master
|
||||
* sdk-202405
|
||||
remotes/origin/HEAD -> origin/master
|
||||
remotes/origin/app_test
|
||||
remotes/origin/master
|
||||
remotes/origin/sdk-202402
|
||||
remotes/origin/sdk-202405
|
||||
```
|
||||
|
||||
## 1.5. 多仓库管理
|
||||
|
||||
### 1.5.1. 合并两个无关联记录的仓库
|
||||
|
||||
  在一个仓库上合并另外一个无关联记录的仓库。
|
||||
|
||||
```code
|
||||
# 假设A仓库的代码合入到B仓库
|
||||
# 在需要合并的仓库A下面执行
|
||||
$ rm -rf .git # 如果不需要A仓库的修改记录,需要重新创建一个新的本地分支和记录;
|
||||
$ git init # 初始化一个空的仓库,并创建.git目录;
|
||||
$ git add . # 添加A仓库的代码;
|
||||
$ git commit -m "new log" # 保存代码,创建新的log;此时创建了一个本地的master分支;
|
||||
$ git remote add B <B仓库的地址> # 添加B仓库的地址;
|
||||
$ git fetch B # 拉取B仓库的信息;
|
||||
$ git checkout -b open B/master # 创建一个B仓库的本地分支,并切换到该分支;
|
||||
$ git merge master --allow-unrelated-histories # 合并A仓库的代码,并允许两个分支没有关联记录;
|
||||
$ git checkout --theirs . # 合并如果有冲突,选择A仓库的代码;
|
||||
$ git restore --source=master output_files/libs/ # 按需,恢复A仓库的某些代码;
|
||||
$ git add . # 添加需要合并的代码;
|
||||
$ git commit -m "merge log" # 合并后的代码,保存到本地仓库;
|
||||
$ git push B open:master # 推送到B仓库的master分支;
|
||||
```
|
||||
|
||||
## 1.6. 存疑
|
||||
|
||||
* 不同的分支之间如何同步某个文件?
|
20
doc/huntting_project_report.md
Normal file
20
doc/huntting_project_report.md
Normal file
|
@ -0,0 +1,20 @@
|
|||
# 1. 项目进度汇总
|
||||
|
||||
## 1.1. 软件开发进度
|
||||
|
||||
```mermaid
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
title 软件进度-3月
|
||||
section 3月
|
||||
6帧探RTSP推流 : done, rtsp_media, 2024-03-18,3d
|
||||
SC230AI快启验证(快启报错) : crit, active, 2024-03-21,3d
|
||||
6帧探视频回放 : active, 2024-03-25,3d
|
||||
```
|
||||
|
||||
### 1.1.1. 总结
|
||||
|
||||
* 截至2024-3-25:
|
||||
1. 6侦探协议框架含http和tcp,http协议框架开发完成,rtsp推流到手机APP完成;
|
||||
2. 存在问题:rtsp推流存在卡顿问题,待优化;
|
||||
3. 更换SC230AI调试快启,快启报错,需要提问题单找原厂协助;
|
101
doc/markdown_user_guide.md
Normal file
101
doc/markdown_user_guide.md
Normal file
|
@ -0,0 +1,101 @@
|
|||
# 1. Markdown使用手册
|
||||
|
||||
## 1.1. 概述
|
||||
|
||||
使用markdown编辑开发文档有以下好处:
|
||||
|
||||
* markdown语法是一种语言,类似代码一样可以方便git管理,查看修改记录;
|
||||
* 对代码显示支持良好;
|
||||
* 可以进行UML类图和时序图的编辑/迭代/维护(强烈推荐);
|
||||
|
||||
## 1.2. 如何使用Markdown
|
||||
|
||||
此处介绍基于vscode编辑环境下使用Markdown的方法:
|
||||
|
||||
* 首先安装vscode插件:
|
||||
1. Markdown All in One
|
||||
2. Markdown Preview Enhanced
|
||||
* 使用Markdown语法编辑开发文档,并使用vscode预览;
|
||||
* 右键使用浏览器打开并打印可生成PDF文档;
|
||||
|
||||
## 1.3. 基本语法介绍
|
||||
|
||||
提供常用语法参考,直接copy模块代码进行编辑。
|
||||
|
||||
### 1.3.1. 常用命令
|
||||
|
||||
```
|
||||
Markdown All in One: Create Table of Contents 创建目录
|
||||
Markdown All in One: Update Table of Contents 更新目录
|
||||
Markdown All in One: Add/Update section numbers 添加 / 更新章节编号
|
||||
Markdown All in One: Remove section numbers 删除章节编号
|
||||
Markdown All in One: Toggle code span 触发设置代码范围(`code`)
|
||||
Markdown All in One: Toggle code block 触发设置代码块(```codes```)
|
||||
Markdown All in One: Print current document to HTML
|
||||
Markdown All in One: Toggle math environment 触发设置数学环境
|
||||
Markdown All in One: Toggle list 触发设置列表环境
|
||||
```
|
||||
|
||||
### 1.3.2. 代码段
|
||||
|
||||
```
|
||||
/*This is your code.*/
|
||||
#include <stdio.h>
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### 1.3.3. UML类图语法
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
Animal <|-- Fish:继承
|
||||
Animal <|.. Zebra:实现
|
||||
Animal : +int age
|
||||
Animal : +String gender
|
||||
Animal: +isMammal()
|
||||
Animal: +mate()
|
||||
class Animal{
|
||||
<<interface>>
|
||||
+call() int
|
||||
}
|
||||
class Fish{
|
||||
-int sizeInFeet
|
||||
-canEat()
|
||||
}
|
||||
class Zebra{
|
||||
<<class>>
|
||||
-func(int, int) int
|
||||
+bool is_wild
|
||||
+run(void)
|
||||
}
|
||||
```
|
||||
|
||||
实现:一般指对抽象类的实例类 \
|
||||
继承:一般指对普通功能基类的派生/重载
|
||||
|
||||
### 1.3.4. UML时序图
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
Alice->>+Jhon:Call function
|
||||
Jhon->>Jhon:handle
|
||||
Jhon-->>-Alice:Call return
|
||||
note left of Alice:function
|
||||
|
||||
Alice->>+Jhon:Call function
|
||||
Jhon->>+Fancy:Call
|
||||
Fancy-->>-Jhon:Call return
|
||||
Jhon-->>-Alice:Call return
|
||||
|
||||
Alice->>+Jhon:Call function
|
||||
Jhon->>+Fancy:Call
|
||||
Fancy->>-Fancy:End
|
||||
Jhon-->>-Alice:Call return
|
||||
```
|
||||
|
||||
### 1.3.5. 踩坑记录
|
||||
|
||||
1. 状态图不能使用default关键字作为一个状态名称,无法画图;
|
9
doc/sdk_build_guide.md
Normal file
9
doc/sdk_build_guide.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
# 1. SDK构建设计文档
|
||||
|
||||
## 1.1. 概述
|
||||
|
||||
  SDK使用cmake构建,把分层解耦合的独立模块编译成静态库,应用程序根据依赖关系进行自动关联链接。
|
||||
|
||||
## 1.2. 启用/禁用功能模块
|
||||
|
||||
  根据不同的产品需求来启用/禁用功能模块,避免编译不需要的模块。
|
89
doc/vscode_ssh_guide.md
Normal file
89
doc/vscode_ssh_guide.md
Normal file
|
@ -0,0 +1,89 @@
|
|||
# 1. vscode使用ssh链接虚拟机服务器
|
||||
|
||||
# 2. 前言
|
||||
|
||||
   在vscode使用ssh工具远程登录虚拟机服务器进行代码编辑。
|
||||
|
||||
| 内容 | 时间 | 作者 | 备注 |
|
||||
|----|----|----|----|
|
||||
| 首版 | 2024-2-26 | xjz | - |
|
||||
|
||||
## 2.1. Windows系统
|
||||
|
||||
* 安装ssh
|
||||
|
||||
   直接安装git工具即可支持ssh
|
||||
|
||||
安装完后确认:
|
||||
```
|
||||
xiaojiazhu@ubuntu:~/project/rkipc/battery/ipc-rk1106/ipc-sdk/cmake-shell$ ssh
|
||||
usage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface]
|
||||
[-b bind_address] [-c cipher_spec] [-D [bind_address:]port]
|
||||
[-E log_file] [-e escape_char] [-F configfile] [-I pkcs11]
|
||||
[-i identity_file] [-J [user@]host[:port]] [-L address]
|
||||
[-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
|
||||
[-Q query_option] [-R address] [-S ctl_path] [-W host:port]
|
||||
[-w local_tun[:remote_tun]] destination [command]
|
||||
```
|
||||
|
||||
* vscode安装ssh插件
|
||||
|
||||
   使用 Remote - SSH 插件
|
||||
|
||||
* ssh密钥配置
|
||||
|
||||
1. Windows生成密钥;
|
||||
2. 把xxx.pub文件内容拷贝到虚拟机的ssh目录下的authorized_keys文件;
|
||||
此处是:
|
||||
|
||||
```
|
||||
xiaojiazhu@ubuntu:~/project/.ssh$ pwd
|
||||
/home/xiaojiazhu/project/.ssh
|
||||
xiaojiazhu@ubuntu:~/project/.ssh$ ls
|
||||
authorized_keys id_rsa id_rsa.pub
|
||||
```
|
||||
|
||||
这样设置后,每次登录ssh无需手动输入密码;
|
||||
|
||||
3. 在Windows远程登录虚拟机:
|
||||
|
||||
参考命令:ssh xiaojiazhu@192.168.1.29
|
||||
|
||||
```
|
||||
PS C:\Users\xjz\.ssh> ssh xiaojiazhu@192.168.1.29
|
||||
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.15.0-94-generic x86_64)
|
||||
|
||||
* Documentation: https://help.ubuntu.com
|
||||
* Management: https://landscape.canonical.com
|
||||
* Support: https://ubuntu.com/advantage
|
||||
|
||||
Expanded Security Maintenance for Applications is not enabled.
|
||||
|
||||
75 updates can be applied immediately.
|
||||
To see these additional updates run: apt list --upgradable
|
||||
|
||||
9 additional security updates can be applied with ESM Apps.
|
||||
Learn more about enabling ESM Apps service at https://ubuntu.com/esm
|
||||
|
||||
New release '22.04.3 LTS' available.
|
||||
Run 'do-release-upgrade' to upgrade to it.
|
||||
|
||||
Your Hardware Enablement Stack (HWE) is supported until April 2025.
|
||||
*** System restart required ***
|
||||
Last login: Sun Feb 25 17:20:04 2024 from 192.168.1.29
|
||||
xiaojiazhu@ubuntu:~$
|
||||
```
|
||||
## 2.2. vscode设置
|
||||
|
||||
配置文件参考
|
||||
|
||||
```
|
||||
Host dgiot // 自定义的主机名
|
||||
HostName 192.168.1.29 // 远端的IP地址
|
||||
User xiaojiazhu 用户名
|
||||
Port 22
|
||||
IdentityFile "C:\Users\xjz\.ssh\id_ed25519" // 本端的私钥文件路径
|
||||
ForwardAgent yes // 忽略
|
||||
```
|
||||
|
||||
多个远端IP复制即可。
|
3
external/.gitignore
vendored
3
external/.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
|
||||
goahead-5.2.0/GoAhead
|
||||
ffmpeg/ffmpeg-6.1.1
|
||||
ffmpeg/ffmpeg-6.1.1
|
||||
fdk-aac/fdk-aac-2.0.3
|
36
external/CMakeLists.txt
vendored
36
external/CMakeLists.txt
vendored
|
@ -3,21 +3,29 @@ add_subdirectory(sqlite3/sqlite-3430000)
|
|||
add_subdirectory(goahead-5.2.0)
|
||||
|
||||
# ================= httpserver ================= #
|
||||
find_program(M4 m4)
|
||||
if(NOT M4)
|
||||
message("m4 not found. Install before continuing.")
|
||||
execute_process(COMMAND sudo apt-get install m4
|
||||
WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/gtest/)
|
||||
endif()
|
||||
find_program(RAGEL ragel)
|
||||
if(NOT RAGEL)
|
||||
message(FATAL_ERROR "ragel not found. Install before continuing.")
|
||||
execute_process(COMMAND sudo apt-get install ragel
|
||||
WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/gtest/)
|
||||
endif()
|
||||
add_subdirectory(httpserver.h-master/src)
|
||||
# Do not delete this module, it is just disabled for compilation because it is not used.
|
||||
# 不要删掉该模块,此处只是因为未使用而屏蔽掉编译。
|
||||
# find_program(M4 m4)
|
||||
# if(NOT M4)
|
||||
# message("m4 not found. Install before continuing.")
|
||||
# execute_process(COMMAND sudo apt-get install m4
|
||||
# WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/)
|
||||
# endif()
|
||||
# find_program(RAGEL ragel)
|
||||
# if(NOT RAGEL)
|
||||
# message("ragel not found. Now install.")
|
||||
# execute_process(COMMAND sudo apt-get install ragel
|
||||
# WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/)
|
||||
# endif()
|
||||
# add_subdirectory(httpserver.h-master/src)
|
||||
# ================= httpserver end ================= #
|
||||
|
||||
add_subdirectory(cJSON-1.7.17)
|
||||
add_subdirectory(libhv/libhv-1.3.2)
|
||||
add_subdirectory(ffmpeg)
|
||||
# ================= ffmpeg related ================= #
|
||||
add_subdirectory(ffmpeg)
|
||||
add_subdirectory(fdk-aac)
|
||||
# ================= ffmpeg related end ================= #
|
||||
add_subdirectory(libconfig)
|
||||
# add_subdirectory(libfaac)
|
||||
add_subdirectory(lvgl_simulator)
|
26
external/fdk-aac/CMakeLists.txt
vendored
Normal file
26
external/fdk-aac/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake)
|
||||
set(FDK_AAC_INSTALL_PATH "${EXTERNAL_LIBS_OUTPUT_PATH}/fdk-aac")
|
||||
set(EXTERNAL_LIBS_PATH "${EXTERNAL_LIBS_PATH};${FDK_AAC_INSTALL_PATH}/lib" CACHE STRING INTERNAL FORCE)
|
||||
message("Compile fdk-aac cmake config files : ${PLATFORM_PATH}/build/cmake/toolchain/linux.toolchain.cmake")
|
||||
add_custom_target(
|
||||
fdk_aac
|
||||
COMMAND echo "Now compile fdk-aac, please wait..."
|
||||
COMMAND test -f ${EXTERNAL_SOURCE_PATH}/fdk-aac/fdk-aac-2.0.3/CMakeLists.txt || tar -xf fdk-aac-2.0.3.tar.gz
|
||||
COMMAND chmod 777 -R fdk-aac-2.0.3
|
||||
COMMAND test -f ${EXTERNAL_SOURCE_PATH}/fdk-aac/fdk-aac-2.0.3/build/Makefile || mkdir fdk-aac-2.0.3/build
|
||||
COMMAND cd fdk-aac-2.0.3/build && cmake ../ -DCMAKE_TOOLCHAIN_FILE=${PLATFORM_PATH}/build/cmake/toolchain/linux.toolchain.cmake
|
||||
-DCMAKE_INSTALL_PREFIX=${FDK_AAC_INSTALL_PATH} -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF
|
||||
COMMAND cd fdk-aac-2.0.3/build && make
|
||||
COMMAND cd fdk-aac-2.0.3/build && make install
|
||||
COMMAND cd fdk-aac-2.0.3/build && make clean
|
||||
WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/fdk-aac/
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
remove_fdk-aac_source_files
|
||||
COMMAND rm -rf fdk-aac-2.0.3
|
||||
WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/fdk-aac/
|
||||
)
|
||||
|
||||
# 将clean目标依赖于我们自定义的clean_script目标
|
||||
add_dependencies(sdk_clean remove_fdk-aac_source_files)
|
BIN
external/fdk-aac/fdk-aac-2.0.3.tar.gz
vendored
Executable file
BIN
external/fdk-aac/fdk-aac-2.0.3.tar.gz
vendored
Executable file
Binary file not shown.
69
external/ffmpeg/CMakeLists.txt
vendored
69
external/ffmpeg/CMakeLists.txt
vendored
|
@ -1,38 +1,57 @@
|
|||
|
||||
|
||||
set(FFMPEG_INSTALL_PATH "${EXTERNAL_LIBS_OUTPUT_PATH}/ffmpeg")
|
||||
set(EXTERNAL_LIBS_PATH "${EXTERNAL_LIBS_PATH};${FFMPEG_INSTALL_PATH}/lib" CACHE STRING INTERNAL FORCE)
|
||||
find_program(NASM nasm)
|
||||
if(NOT NASM)
|
||||
message("nasm not found. Now install.")
|
||||
execute_process(COMMAND sudo apt install nasm WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/)
|
||||
endif()
|
||||
set(FFMPEG_COMMON_CONFIG "--enable-cross-compile --target-os=linux \
|
||||
--cc=${CMAKE_C_COMPILER} \
|
||||
--cxx=${CMAKE_CXX_COMPILER} \
|
||||
--prefix=${FFMPEG_INSTALL_PATH} \
|
||||
--enable-parsers --disable-decoders --enable-decoder=h264 --enable-libfdk-aac \
|
||||
--disable-debug --enable-ffmpeg --enable-static --disable-stripping --disable-doc \
|
||||
--enable-gpl --enable-nonfree --enable-version3 --enable-small \
|
||||
--disable-mipsdsp --disable-mipsdspr2 \
|
||||
--disable-encoders \
|
||||
--disable-muxers --enable-muxer=mov --enable-muxer=mp4 --enable-encoder=mpeg4 \
|
||||
--enable-decoder=aac --enable-encoder=aac --enable-encoder=libfdk_aac --enable-decoder=pcm_alaw --enable-encoder=pcm_alaw \
|
||||
--enable-demuxer=mov \
|
||||
--disable-protocols --enable-protocol=file \
|
||||
--disable-bsfs --enable-bsf=aac_adtstoasc --enable-bsf=h264_mp4toannexb --enable-bsf=hevc_mp4toannexb \
|
||||
--disable-indevs --disable-outdevs --enable-muxer=image2 --enable-encoder=mjpeg \
|
||||
--extra-libs=-lm \
|
||||
--extra-cflags=\"-I${EXTERNAL_LIBS_OUTPUT_PATH}/fdk-aac/include\" \
|
||||
--extra-ldflags=\"-L${EXTERNAL_LIBS_OUTPUT_PATH}/fdk-aac/lib\"")
|
||||
if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX})
|
||||
set(CONFIGURE_COMMAND "${FFMPEG_COMMON_CONFIG} --arch=x86_64")
|
||||
else()
|
||||
set(CONFIGURE_COMMAND "${FFMPEG_COMMON_CONFIG} --arch=arm64 --disable-asm")
|
||||
endif()
|
||||
message("Compile ffmpeg comand : ${CONFIGURE_COMMAND}")
|
||||
add_custom_command(
|
||||
OUTPUT ${EXTERNAL_LIBS_OUTPUT_PATH}/fdk-aac/lib/libfdk-aac.a
|
||||
COMMAND echo "Did not found fdk-aac lib in output_files, now compile fdk-aac."
|
||||
COMMAND make fdk_aac
|
||||
WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/
|
||||
)
|
||||
add_custom_target(
|
||||
ffmpeg
|
||||
# DEPENDS ${EXTERNAL_LIBS_OUTPUT_PATH}/libgo.a
|
||||
# COMMAND mkdir ${GOAHEAD_UPLOAD_TMP_PATH}
|
||||
# COMMAND cp ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/modify/http.c ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/GoAhead/src
|
||||
# COMMAND touch ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/GoAhead/src/http.c
|
||||
COMMAND test -f ${EXTERNAL_SOURCE_PATH}/ffmpeg/Makefile || tar -xf ffmpeg_6.1.1.orig.tar.xz
|
||||
COMMAND cd ffmpeg-6.1.1 && ./configure --enable-cross-compile --target-os=linux --arch=arm64
|
||||
--cc=${CMAKE_C_COMPILER}
|
||||
--cxx=${CMAKE_CXX_COMPILER}
|
||||
--prefix=${EXTERNAL_LIBS_OUTPUT_PATH}/ffmpeg
|
||||
--disable-asm --enable-parsers --disable-decoders --enable-decoder=h264
|
||||
--disable-debug --enable-ffmpeg --enable-shared --enable-static --disable-stripping --disable-doc
|
||||
--enable-gpl --enable-nonfree --enable-version3 --enable-small
|
||||
--disable-mipsdsp --disable-mipsdspr2
|
||||
--disable-encoders
|
||||
--disable-muxers --enable-muxer=mov --enable-muxer=mp4
|
||||
--disable-decoders --enable-decoder=aac
|
||||
--disable-filters
|
||||
--disable-demuxers --enable-demuxer=mov
|
||||
--disable-parsers
|
||||
--disable-protocols --enable-protocol=file
|
||||
--disable-bsfs --enable-bsf=aac_adtstoasc --enable-bsf=h264_mp4toannexb --enable-bsf=hevc_mp4toannexb
|
||||
--disable-indevs
|
||||
--disable-outdevs --disable-ffprobe --disable-ffmpeg --disable-ffplay --disable-debug
|
||||
DEPENDS ${EXTERNAL_LIBS_OUTPUT_PATH}/fdk-aac/lib/libfdk-aac.a
|
||||
COMMAND echo "Now compile ffmpeg, please wait..."
|
||||
COMMAND test -f ${EXTERNAL_SOURCE_PATH}/ffmpeg/ffmpeg-6.1.1/Makefile || tar -xf ffmpeg_6.1.1.orig.tar.xz
|
||||
COMMAND chmod 777 -R ffmpeg-6.1.1
|
||||
COMMAND cd ffmpeg-6.1.1 && bash -c "./configure ${CONFIGURE_COMMAND}"
|
||||
COMMAND cd ffmpeg-6.1.1 && make
|
||||
COMMAND cd ffmpeg-6.1.1 && make install
|
||||
COMMAND cd ffmpeg-6.1.1 && make clean
|
||||
WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/ffmpeg/
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
remove_ffmpeg_source_files
|
||||
COMMAND rm -rf ffmpeg-6.1.1
|
||||
COMMAND rm -rf ${FFMPEG_INSTALL_PATH}
|
||||
WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/ffmpeg/
|
||||
)
|
||||
|
||||
|
|
133
external/ffmpeg/README.md
vendored
Normal file
133
external/ffmpeg/README.md
vendored
Normal file
|
@ -0,0 +1,133 @@
|
|||
# 1. ffmpeg开发文档
|
||||
|
||||
## 1.1. ffplay命令使用
|
||||
|
||||
* 播放G711a音频文件
|
||||
|
||||
```code
|
||||
$ ffplay -i audio.g711a -f alaw -ac 1 -ar 8000
|
||||
```
|
||||
ffmpeg -i input.g711a -acodec alaw output.wav
|
||||
|
||||
* 播放h264视频文件
|
||||
|
||||
```code
|
||||
$ ffplay video.h264
|
||||
```
|
||||
|
||||
* g711a音频文件转wav音频文件
|
||||
|
||||
```code
|
||||
$ fmpeg -f mulaw -ar 8000 -i audio.g711a audio.wav
|
||||
```
|
||||
|
||||
* 播放pcm文件
|
||||
|
||||
```code
|
||||
$ ffplay -f s16le -ar 8000 -ac 1 test.pcm
|
||||
```
|
||||
|
||||
* 生成jpeg
|
||||
|
||||
```code
|
||||
$ ./ffmpeg -i test.h264 -vframes 1 -vf "scale=640:480:force_original_aspect_ratio=decrease" -f image2 output.jpeg
|
||||
```
|
||||
|
||||
```code
|
||||
void FfmpegThumbnail::GetDecodeDataCallback(AVFrame *frame)
|
||||
{
|
||||
LogInfo("GetDecodeDataCallback frame->width = %d, frame->height = %d\n", frame->width, frame->height);
|
||||
|
||||
// Allocate output frame for YUV420P format
|
||||
AVFrame *output_frame = av_frame_alloc();
|
||||
output_frame->format = AV_PIX_FMT_YUV420P;
|
||||
output_frame->width = 640;
|
||||
output_frame->height = 480;
|
||||
|
||||
// Calculate buffer size for YUV420P
|
||||
int yuv_buf_size = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, 640, 480, 1);
|
||||
uint8_t *yuv_buf = (uint8_t *)av_malloc(yuv_buf_size);
|
||||
|
||||
// Fill output frame with YUV420P buffer
|
||||
av_image_fill_arrays(output_frame->data, output_frame->linesize, yuv_buf, AV_PIX_FMT_YUV420P, 640, 480, 1);
|
||||
|
||||
// Create SwsContext for pixel format conversion from YUV420P (1920x2160) to YUV420P (640x480)
|
||||
SwsContext *sws_ctx = sws_getContext(frame->width, frame->height, static_cast<AVPixelFormat>(frame->format),
|
||||
output_frame->width, output_frame->height, AV_PIX_FMT_YUV420P,
|
||||
SWS_BILINEAR, nullptr, nullptr, nullptr);
|
||||
if (!sws_ctx) {
|
||||
LogError("Failed to create SwsContext for pixel format conversion\n");
|
||||
av_frame_free(&output_frame);
|
||||
av_free(yuv_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
// Perform pixel format conversion and scaling
|
||||
sws_scale(sws_ctx, frame->data, frame->linesize, 0, frame->height,
|
||||
output_frame->data, output_frame->linesize);
|
||||
|
||||
// Clean up SwsContext
|
||||
sws_freeContext(sws_ctx);
|
||||
|
||||
// Encode the YUV420P frame to JPEG using mEncoder
|
||||
if (mEncoder) {
|
||||
mEncoder->EncodeData(output_frame, mStream, mEncodeCallback);
|
||||
}
|
||||
|
||||
// Free allocated resources
|
||||
av_frame_free(&output_frame);
|
||||
av_free(yuv_buf);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
* 将h264和wav文件合成mp4文件
|
||||
|
||||
**注意:未发现可以将h264和g711a文件合成mp4文件**
|
||||
|
||||
```code
|
||||
$ ffmpeg -i video.h264 -i audio.wav -c:v copy -c:a aac -b:a 96k test.mp4
|
||||
```
|
||||
|
||||
## 1.2. 问题记录
|
||||
|
||||
### 1.2.1. avformat_open_input 执行失败
|
||||
|
||||
  在执行avformat_open_input时,返回-1094995529<0,错误
|
||||
|
||||
解决:在Ubuntu编译时,使能所有的编译选项,并且把--arch=赋值为linux
|
||||
|
||||
```code
|
||||
# 详见://external/ffmpeg/CMakeLists.txt
|
||||
set(CONFIGURE_COMMAND "--enable-cross-compile --target-os=linux --arch=linux \
|
||||
--cc=${CMAKE_C_COMPILER} \
|
||||
--cxx=${CMAKE_CXX_COMPILER} \
|
||||
--prefix=${EXTERNAL_LIBS_OUTPUT_PATH}/ffmpeg \
|
||||
--enable-parsers --enable-decoder=h264 \
|
||||
--enable-ffmpeg --enable-shared --enable-static \
|
||||
--enable-gpl --enable-nonfree --enable-version3 --enable-small \
|
||||
--enable-muxer=mov --enable-muxer=mp4 \
|
||||
--enable-decoder=aac \
|
||||
--enable-demuxer=mov \
|
||||
--enable-protocol=file --enable-bsf=aac_adtstoasc --enable-bsf=h264_mp4toannexb --enable-bsf=hevc_mp4toannexb")
|
||||
```
|
||||
|
||||
### 1.2.2. avformat_open_input 执行失败
|
||||
|
||||
  打开g711a文件时,提示无效数据。如下:
|
||||
**Invalid data found when processing input**
|
||||
|
||||
解决:
|
||||
调用 avformat_open_input 函数时,指定输入文件的格式(第三个参数),g711a文件格式为:alaw。
|
||||
|
||||
```code
|
||||
# //utils/MediaBase/src/MediaBaseImpl.cpp
|
||||
const AVInputFormat *iformat = av_find_input_format(InputFormat(mType));
|
||||
AVFormatContext *pFormatCtx = nullptr;
|
||||
if ((result = avformat_open_input(&pFormatCtx, path.c_str(), iformat, nullptr)) < 0) {
|
||||
char error_str[AV_ERROR_MAX_STRING_SIZE] = {0};
|
||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, result);
|
||||
LogError("Couldn't open file: %s, result=%s\n", path.c_str(), error_str);
|
||||
return CreateStatusCode(STATUS_CODE_NOT_OK);
|
||||
}
|
||||
```
|
30
external/goahead-5.2.0/CMakeLists.txt
vendored
30
external/goahead-5.2.0/CMakeLists.txt
vendored
|
@ -1,4 +1,30 @@
|
|||
include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake)
|
||||
include(${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/goahead.cmake)
|
||||
set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH})
|
||||
set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH})
|
||||
include(${UTILS_SOURCE_PATH}/WebServer/build/webserver.cmake)
|
||||
add_custom_target(
|
||||
goahead-5.2.0
|
||||
COMMAND test -f ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/GoAhead/Makefile || tar zxvf goahead-5.2.0.tar.gz
|
||||
COMMAND cp ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/modify/http.c ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/GoAhead/src
|
||||
COMMAND chmod 777 -R GoAhead
|
||||
COMMAND cd GoAhead && make CC=${CMAKE_C_COMPILER} ARCH=${SET_ARCH} PROFILE=${LIB_TYPE} ME_GOAHEAD_UPLOAD_DIR=\"${GOAHEAD_UPLOAD_TMP_PATH}\"
|
||||
ME_GOAHEAD_SSL_KEY=\"${GOAHEAD_CONFIG_FILE_PATH}/self.key\" ME_GOAHEAD_SSL_CERTIFICATE=\"${GOAHEAD_CONFIG_FILE_PATH}/self.crt\"
|
||||
${ME_GOAHEAD_LIMIT_POST} -f ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/modify/goahead-linux-static-fancy.mk
|
||||
COMMAND echo "Copy goahead lib to output path."
|
||||
COMMAND mv ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/GoAhead/build/${GOAHEAD_INCLUDE_PATH}/bin/libgo.a ${EXTERNAL_LIBS_OUTPUT_PATH}/libgo.a
|
||||
COMMAND mv ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/GoAhead/build/${GOAHEAD_INCLUDE_PATH}/bin/libmbedtls.a ${EXTERNAL_LIBS_OUTPUT_PATH}/libmbedtls.a
|
||||
COMMAND mv ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/GoAhead/build/${GOAHEAD_INCLUDE_PATH}/bin/libgoahead-mbedtls.a ${EXTERNAL_LIBS_OUTPUT_PATH}/libgoahead-mbedtls.a
|
||||
COMMAND cp ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/GoAhead/build/${GOAHEAD_INCLUDE_PATH}/bin/self.crt ${PLATFORM_PATH}/cmake-shell/
|
||||
COMMAND cp ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/GoAhead/build/${GOAHEAD_INCLUDE_PATH}/bin/self.key ${PLATFORM_PATH}/cmake-shell/
|
||||
COMMAND cp ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/GoAhead/test/route.txt ${PLATFORM_PATH}/cmake-shell/
|
||||
COMMAND cp ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/GoAhead/test/auth.txt ${PLATFORM_PATH}/cmake-shell/
|
||||
WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
remove_goahead_source_files
|
||||
COMMAND rm -rf GoAhead
|
||||
WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/goahead-5.2.0/
|
||||
)
|
||||
|
||||
# 将clean目标依赖于我们自定义的clean_script目标
|
||||
add_dependencies(sdk_clean remove_goahead_source_files)
|
27
external/libconfig/CMakeLists.txt
vendored
Normal file
27
external/libconfig/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
set(LIBCONFIG_INSTALL_PATH "${EXTERNAL_LIBS_OUTPUT_PATH}/libconfig")
|
||||
if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX})
|
||||
set(CONFIGURE_COMMAND "--disable-cxx --enable-static=yes --prefix=${LIBCONFIG_INSTALL_PATH}")
|
||||
else()
|
||||
set(CONFIGURE_COMMAND "--host=${COMPILE_HOST} --disable-cxx --enable-static=yes --prefix=${LIBCONFIG_INSTALL_PATH}")
|
||||
endif()
|
||||
message("Compile libconfig comand : ${CONFIGURE_COMMAND}")
|
||||
set(EXTERNAL_LIBS_PATH "${EXTERNAL_LIBS_PATH};${LIBCONFIG_INSTALL_PATH}/lib" CACHE STRING INTERNAL FORCE)
|
||||
add_custom_target(
|
||||
libconfig
|
||||
COMMAND test -f ${EXTERNAL_SOURCE_PATH}/libconfig-1.7.3/Makefile || tar zxvf libconfig-1.7.3.tar.gz
|
||||
COMMAND chmod 777 -R libconfig-1.7.3
|
||||
# COMMAND cd libconfig-1.7.3 && ./configure --disable-cxx --enable-static=yes --prefix=${LIBCONFIG_INSTALL_PATH}
|
||||
COMMAND cd libconfig-1.7.3 && bash -c "./configure ${CONFIGURE_COMMAND}"
|
||||
COMMAND cd libconfig-1.7.3 && make
|
||||
COMMAND cd libconfig-1.7.3 && make install
|
||||
COMMAND cd libconfig-1.7.3 && make clean
|
||||
WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/libconfig/
|
||||
)
|
||||
add_custom_target(
|
||||
remove_libconfig_source_files
|
||||
COMMAND rm -rf libconfig-1.7.3
|
||||
WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/libconfig/
|
||||
)
|
||||
|
||||
# 将clean目标依赖于我们自定义的clean_script目标
|
||||
add_dependencies(sdk_clean remove_libconfig_source_files)
|
12
external/libfaac/CMakeLists.txt
vendored
Executable file
12
external/libfaac/CMakeLists.txt
vendored
Executable file
|
@ -0,0 +1,12 @@
|
|||
include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake)
|
||||
set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH})
|
||||
set(LIBRARY_OUTPUT_PATH ${EXTERNAL_LIBS_OUTPUT_PATH})
|
||||
INCLUDE_DIRECTORIES(libfaac)
|
||||
INCLUDE_DIRECTORIES(./)
|
||||
|
||||
AUX_SOURCE_DIRECTORY(. MODULE_SRC)
|
||||
AUX_SOURCE_DIRECTORY(libfaac MODULE_SRC)
|
||||
|
||||
ADD_LIBRARY(faac STATIC ${MODULE_SRC})
|
||||
|
||||
|
31
external/libfaac/G711AToPcm.cpp
vendored
Normal file
31
external/libfaac/G711AToPcm.cpp
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
|
||||
#include "G711AToPcm.h"
|
||||
|
||||
#include "g711.h"
|
||||
|
||||
|
||||
G711AToPcm::G711AToPcm(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
G711AToPcm::~G711AToPcm(void)
|
||||
{
|
||||
}
|
||||
unsigned short G711AToPcm::DecodeOneChar(unsigned char data)
|
||||
{
|
||||
return (int16_t)alaw2linear(data);
|
||||
}
|
||||
//-------------------------------------------
|
||||
G711UToPcm::G711UToPcm(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
G711UToPcm::~G711UToPcm(void)
|
||||
{
|
||||
}
|
||||
unsigned short G711UToPcm::DecodeOneChar(unsigned char data)
|
||||
{
|
||||
return (int16_t)ulaw2linear(data);
|
||||
}
|
24
external/libfaac/G711AToPcm.h
vendored
Normal file
24
external/libfaac/G711AToPcm.h
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
|
||||
#pragma once
|
||||
#include "IDecodeToPcm.h"
|
||||
|
||||
class G711AToPcm :
|
||||
public DecodeToPcmBase
|
||||
{
|
||||
public:
|
||||
G711AToPcm(void);
|
||||
virtual ~G711AToPcm(void);
|
||||
public:
|
||||
virtual unsigned short DecodeOneChar(unsigned char data);
|
||||
};
|
||||
|
||||
|
||||
class G711UToPcm :
|
||||
public DecodeToPcmBase
|
||||
{
|
||||
public:
|
||||
G711UToPcm(void);
|
||||
virtual ~G711UToPcm(void);
|
||||
public:
|
||||
virtual unsigned short DecodeOneChar(unsigned char data);
|
||||
};
|
90
external/libfaac/IDecodeToPcm.cpp
vendored
Normal file
90
external/libfaac/IDecodeToPcm.cpp
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
|
||||
#include "IDecodeToPcm.h"
|
||||
#include "audio_buffer.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
IDecodeToPcm::IDecodeToPcm(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
IDecodeToPcm::~IDecodeToPcm(void)
|
||||
{
|
||||
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
InAudioInfo::InAudioInfo()
|
||||
{
|
||||
InitParam& initParam = m_initparam;
|
||||
initParam.u32AudioSamplerate=8000;
|
||||
initParam.ucAudioChannel=1;
|
||||
initParam.u32PCMBitSize=16;
|
||||
initParam.ucAudioCodec = Law_ALaw;
|
||||
}
|
||||
InAudioInfo::InAudioInfo(InitParam param):m_initparam(param)
|
||||
{
|
||||
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------
|
||||
DecodeToPcmBase::DecodeToPcmBase(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
DecodeToPcmBase::~DecodeToPcmBase(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int DecodeToPcmBase::Init(InAudioInfo info)
|
||||
{
|
||||
m_g7FrameSize = G711_ONE_LEN;
|
||||
return 0;
|
||||
}
|
||||
int DecodeToPcmBase::PCMSize()
|
||||
{
|
||||
return CON_PCM_SIZE;
|
||||
}
|
||||
int DecodeToPcmBase::G7FrameSize()
|
||||
{
|
||||
return m_g7FrameSize;
|
||||
}
|
||||
int DecodeToPcmBase::Decode(unsigned char* pout_buf, unsigned int* pout_len , unsigned char* pin_buf, unsigned int in_len)
|
||||
{
|
||||
int16_t *dst = (int16_t *) pout_buf;
|
||||
uint8_t *src = (uint8_t *) pin_buf;
|
||||
uint32_t i = 0;
|
||||
int Ret = 0;
|
||||
|
||||
if ((NULL == pout_buf) || \
|
||||
(NULL == pout_len) || \
|
||||
(NULL == pin_buf) || \
|
||||
(0 == in_len))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*pout_len < 2 * in_len)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
//---{{{
|
||||
|
||||
for (i = 0; i < in_len; i++)
|
||||
{
|
||||
*(dst++) = (int16_t)DecodeOneChar(*(src++));
|
||||
}
|
||||
|
||||
//---}}}
|
||||
*pout_len = 2 * in_len;
|
||||
|
||||
Ret = 2 * in_len;
|
||||
return Ret;
|
||||
return 0;
|
||||
}
|
100
external/libfaac/IDecodeToPcm.h
vendored
Normal file
100
external/libfaac/IDecodeToPcm.h
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#ifndef _IDECODETOPCM_H
|
||||
#define _IDECODETOPCM_H
|
||||
|
||||
#include "MtAACEncoderAPI.h"
|
||||
|
||||
#define USE_SHOUT_G711PACK 1
|
||||
|
||||
#if USE_SHOUT_G711PACK
|
||||
#define G711_ONE_LEN 160
|
||||
#define G711_ONE_OFFSET 0
|
||||
|
||||
#else
|
||||
#define G711_ONE_LEN 164
|
||||
#define G711_ONE_OFFSET 4
|
||||
#endif
|
||||
|
||||
const int CON_PCM_SIZE = 320;
|
||||
|
||||
class audio_buffer;
|
||||
|
||||
class InAudioInfo
|
||||
{
|
||||
public:
|
||||
InAudioInfo();
|
||||
InAudioInfo(InitParam param);
|
||||
~InAudioInfo(){;}
|
||||
|
||||
unsigned int CodecType()
|
||||
{
|
||||
return m_initparam.ucAudioCodec;
|
||||
//return m_u32AudioCodec;
|
||||
}
|
||||
unsigned int Samplerate()
|
||||
{
|
||||
return m_initparam.u32AudioSamplerate;
|
||||
//return m_u32AudioSamplerate;
|
||||
}
|
||||
unsigned int Channel()
|
||||
{
|
||||
return m_initparam.ucAudioChannel;
|
||||
//return m_u32AudioChannel;
|
||||
}
|
||||
unsigned int PCMBitSize()
|
||||
{
|
||||
return m_initparam.u32PCMBitSize;
|
||||
//return m_nPCMBitSize;
|
||||
}
|
||||
unsigned char G726RateBits()
|
||||
{
|
||||
return m_initparam.g726param.ucRateBits;
|
||||
}
|
||||
private:
|
||||
unsigned int m_u32AudioCodec;
|
||||
unsigned int m_u32AudioSamplerate;
|
||||
unsigned int m_u32AudioChannel;
|
||||
|
||||
unsigned int m_nPCMBitSize;
|
||||
|
||||
InitParam m_initparam;
|
||||
};
|
||||
//----------------------------------------------------------
|
||||
class IDecodeToPcm
|
||||
{
|
||||
public:
|
||||
IDecodeToPcm(void);
|
||||
virtual ~IDecodeToPcm(void);
|
||||
|
||||
public:
|
||||
virtual int Init(InAudioInfo info)=0;
|
||||
virtual int Decode( unsigned char* outbuf, unsigned int* outlen , unsigned char* inbuf, unsigned int inlen)=0;
|
||||
virtual int PCMSize()=0;
|
||||
virtual int G7FrameSize()=0;
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------
|
||||
class DecodeToPcmBase:public IDecodeToPcm
|
||||
{
|
||||
public:
|
||||
DecodeToPcmBase();
|
||||
virtual ~DecodeToPcmBase();
|
||||
|
||||
int Init(InAudioInfo info);
|
||||
|
||||
public:
|
||||
virtual int Decode(unsigned char* outbuf, unsigned int* outlen , unsigned char* inbuf, unsigned int inlen);
|
||||
virtual int PCMSize();
|
||||
virtual int G7FrameSize();
|
||||
|
||||
virtual unsigned short DecodeOneChar(unsigned char data)=0;
|
||||
|
||||
private:
|
||||
int m_g7FrameSize;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
190
external/libfaac/MtAACEncoder.cpp
vendored
Normal file
190
external/libfaac/MtAACEncoder.cpp
vendored
Normal file
|
@ -0,0 +1,190 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "MtAACEncoder.h"
|
||||
#include "MtAACEncoderAPI.h"
|
||||
#include "outDebug.h"
|
||||
#include "G711AToPcm.h"
|
||||
#include "condef.h"
|
||||
|
||||
G7ToAac::G7ToAac()
|
||||
{
|
||||
m_pbPCMBuffer = NULL;
|
||||
m_pbAACBuffer = NULL;
|
||||
m_pbG7FrameBuffer = NULL;
|
||||
m_pbPCMTmpBuffer = NULL;
|
||||
m_audio_buffer_ = NULL;
|
||||
m_pDecodeToPcm = NULL;
|
||||
m_pPCMToAAC = NULL;
|
||||
}
|
||||
|
||||
G7ToAac::~G7ToAac()
|
||||
{
|
||||
/*free the source of malloc*/
|
||||
SAFE_FREE_BUF(m_pbPCMBuffer);
|
||||
SAFE_FREE_BUF(m_pbAACBuffer);
|
||||
SAFE_FREE_BUF(m_pbG7FrameBuffer);
|
||||
SAFE_FREE_BUF(m_pbPCMTmpBuffer);
|
||||
|
||||
SAFE_DELETE_OBJ(m_audio_buffer_);
|
||||
SAFE_DELETE_OBJ(m_pDecodeToPcm);
|
||||
SAFE_DELETE_OBJ(m_pPCMToAAC);
|
||||
}
|
||||
bool G7ToAac::init()
|
||||
{
|
||||
nRet = 0;
|
||||
nTmp = 0;
|
||||
nCount = 0;
|
||||
nStatus = 0;
|
||||
nPCMRead = 0;
|
||||
|
||||
CreateBuffer();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool G7ToAac::init(InAudioInfo info)
|
||||
{
|
||||
m_inAudioInfo = info;
|
||||
|
||||
bool ret=false;
|
||||
ret = CreateDecodePcm();
|
||||
|
||||
ret = CreateEncodeAac();
|
||||
if (!ret)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return init();
|
||||
}
|
||||
bool G7ToAac::CreateDecodePcm()
|
||||
{
|
||||
if ( Law_ALaw == m_inAudioInfo.CodecType())
|
||||
{
|
||||
m_pDecodeToPcm = new G711AToPcm();
|
||||
}else if ( Law_ULaw == m_inAudioInfo.CodecType() )
|
||||
{
|
||||
m_pDecodeToPcm = new G711UToPcm();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pDecodeToPcm = new G711AToPcm();
|
||||
}
|
||||
m_pDecodeToPcm->Init(m_inAudioInfo);
|
||||
|
||||
return true;
|
||||
}
|
||||
bool G7ToAac::CreateEncodeAac()
|
||||
{
|
||||
m_pPCMToAAC = new PcmToAac();
|
||||
bool ret = m_pPCMToAAC->Init(&m_inAudioInfo);
|
||||
|
||||
return ret;
|
||||
}
|
||||
bool G7ToAac::CreateBuffer()
|
||||
{
|
||||
m_nPCMBufferSize = m_pPCMToAAC->GetPCMBufferSize();
|
||||
m_pbPCMBuffer = (unsigned char*) malloc(m_nPCMBufferSize * sizeof (unsigned char));
|
||||
memset(m_pbPCMBuffer, 0, m_nPCMBufferSize);
|
||||
|
||||
m_nMaxOutputBytes = m_pPCMToAAC->GetMaxOutputBytes();
|
||||
m_pbAACBuffer = (unsigned char*) malloc(m_nMaxOutputBytes * sizeof (unsigned char));
|
||||
memset(m_pbAACBuffer, 0, m_nMaxOutputBytes);
|
||||
|
||||
m_nG7FrameBufferSize = m_pDecodeToPcm->G7FrameSize();
|
||||
m_pbG7FrameBuffer = (unsigned char *) malloc(m_nG7FrameBufferSize * sizeof (unsigned char));
|
||||
memset(m_pbG7FrameBuffer, 0, m_nG7FrameBufferSize);
|
||||
|
||||
m_nPCMSize = m_pDecodeToPcm->PCMSize();
|
||||
m_pbPCMTmpBuffer = (unsigned char *) malloc(m_nPCMSize * sizeof (unsigned char));
|
||||
memset(m_pbPCMTmpBuffer, 0, m_nPCMSize);
|
||||
|
||||
m_audio_buffer_ = new audio_buffer();
|
||||
|
||||
return true;
|
||||
}
|
||||
int G7ToAac::aac_encode(unsigned char* inbuf, unsigned int inlen, unsigned char* outbuf, unsigned int* outlen)
|
||||
{
|
||||
int encodeLen = 0;
|
||||
|
||||
if (NULL != m_pDecodeToPcm)
|
||||
{
|
||||
encodeLen = aac_encode_obj(inbuf , inlen , outbuf , outlen);
|
||||
}
|
||||
|
||||
return encodeLen;
|
||||
}
|
||||
|
||||
int G7ToAac::aac_encode_obj(unsigned char* inbuf, unsigned int inlen, unsigned char* outbuf, unsigned int* outlen )
|
||||
{
|
||||
m_audio_buffer_->write_data(inbuf, inlen);
|
||||
int buffer_len = 0;
|
||||
*outlen = 0;
|
||||
int nPCMSize = 0;
|
||||
//while ((buffer_len = audio_buffer_->get_data(pbG711ABuffer, /*164*/G711_ONE_LEN)) > 0)
|
||||
while ((buffer_len = m_audio_buffer_->get_data(m_pbG7FrameBuffer, m_nG7FrameBufferSize)) > 0)
|
||||
{
|
||||
if (buffer_len <= 0)
|
||||
{
|
||||
if(AAC_DEBUG) printf("%s:[%d] G711A -> PCM no G711 data !\n", __FUNCTION__, __LINE__);
|
||||
//Sleep(100);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nStatus = 0;
|
||||
memset(m_pbPCMTmpBuffer, 0, m_nPCMSize);
|
||||
nPCMSize = m_nPCMSize;
|
||||
//if ((nPCMRead = m_pDecodeToPcm->Decode(pbPCMTmpBuffer, (unsigned int*)&PCMSize, pbG711ABuffer+/*4*/G711_ONE_OFFSET, buffer_len-/*4*/G711_ONE_OFFSET )) < 0) // TODO: skip 4 byte?
|
||||
if ((nPCMRead = m_pDecodeToPcm->Decode(m_pbPCMTmpBuffer, (unsigned int*)&nPCMSize, m_pbG7FrameBuffer, buffer_len )) < 0) // TODO: skip 4 byte?
|
||||
{
|
||||
if(AAC_DEBUG) printf("%s:[%d] G711A -> PCM failed buffer_len = %d !\n", __FUNCTION__, __LINE__, buffer_len);
|
||||
return -1;
|
||||
}
|
||||
//if(AAC_DEBUG) printf("nPCMRead = %d, PCMSize = %d\n", nPCMRead, PCMSize);
|
||||
|
||||
if ((m_nPCMBufferSize - nCount) < nPCMRead)
|
||||
{
|
||||
//if(AAC_DEBUG) printf("nPCMBufferSize = %d, nCount = %d, nPCMRead = %d\n", nPCMBufferSize, nCount, nPCMRead);
|
||||
nStatus = 1;
|
||||
memset(m_pbAACBuffer, 0, m_nMaxOutputBytes);
|
||||
memcpy(m_pbPCMBuffer + nCount, m_pbPCMTmpBuffer, (m_nPCMBufferSize - nCount));
|
||||
|
||||
nRet = m_pPCMToAAC->Encode( (int32_t*)m_pbPCMBuffer , m_nPCMBufferSize , m_pbAACBuffer, m_nMaxOutputBytes);
|
||||
|
||||
|
||||
memcpy(outbuf + *outlen, m_pbAACBuffer, nRet);
|
||||
*outlen += nRet;
|
||||
|
||||
nTmp = nPCMRead - (m_nPCMBufferSize - nCount);
|
||||
memset(m_pbPCMBuffer, 0, m_nPCMBufferSize);
|
||||
memcpy(m_pbPCMBuffer, m_pbPCMTmpBuffer + (m_nPCMBufferSize - nCount), nTmp);
|
||||
if(AAC_DEBUG) printf("%s:[%d] G711A -> PCM (nPCMBufferSize - nCount) < nPCMRead\n", __FUNCTION__, __LINE__);
|
||||
nCount = 0;
|
||||
nCount += nTmp;
|
||||
}
|
||||
|
||||
if (nStatus == 0)
|
||||
{
|
||||
if(AAC_DEBUG) printf("%s:[%d] G711A -> PCM nStatus = 0...\n", __FUNCTION__, __LINE__);
|
||||
memcpy(m_pbPCMBuffer + nCount, m_pbPCMTmpBuffer, nPCMRead);
|
||||
if(AAC_DEBUG) printf("%s:[%d] G711A -> PCM nStatus = 0\n", __FUNCTION__, __LINE__);
|
||||
nCount += nPCMRead;
|
||||
}
|
||||
|
||||
if (nPCMRead < /*320*/CON_PCM_SIZE)
|
||||
{
|
||||
if(AAC_DEBUG) printf("nPCMRead = %d\n", nPCMRead);
|
||||
|
||||
nRet = m_pPCMToAAC->Encode((int*) m_pbPCMBuffer, nCount , m_pbAACBuffer, m_nMaxOutputBytes);
|
||||
|
||||
|
||||
memcpy(outbuf + *outlen, m_pbAACBuffer, nRet);
|
||||
*outlen += nRet;
|
||||
|
||||
INFO_D(AAC_DEBUG , "G711A -> PCM nPCMRead < 320");
|
||||
}
|
||||
}
|
||||
return *outlen;
|
||||
}
|
55
external/libfaac/MtAACEncoder.h
vendored
Normal file
55
external/libfaac/MtAACEncoder.h
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
#ifndef MtAACEncoder_H
|
||||
#define MtAACEncoder_H
|
||||
|
||||
#include "audio_buffer.h"
|
||||
#include "IDecodeToPcm.h"
|
||||
#include "PcmToAac.h"
|
||||
|
||||
class G7ToAac
|
||||
{
|
||||
public:
|
||||
G7ToAac();
|
||||
virtual ~G7ToAac();
|
||||
|
||||
bool init();
|
||||
bool init(InAudioInfo info);
|
||||
|
||||
int aac_encode(unsigned char* inbuf, unsigned int inlen, unsigned char* outbuf, unsigned int* outlen);
|
||||
|
||||
private:
|
||||
int aac_encode_obj(unsigned char* inbuf, unsigned int inlen, unsigned char* outbuf, unsigned int* outlen );
|
||||
|
||||
bool CreateDecodePcm();
|
||||
bool CreateEncodeAac();
|
||||
bool CreateBuffer();
|
||||
private:
|
||||
int nRet;
|
||||
int nTmp;
|
||||
int nCount;
|
||||
int nStatus;
|
||||
int nPCMRead;
|
||||
|
||||
|
||||
|
||||
int m_nPCMBufferSize;
|
||||
unsigned char *m_pbPCMBuffer;
|
||||
|
||||
unsigned long m_nMaxOutputBytes;
|
||||
unsigned char *m_pbAACBuffer;
|
||||
|
||||
int m_nPCMSize;
|
||||
unsigned char *m_pbPCMTmpBuffer;
|
||||
|
||||
unsigned char *m_pbG7FrameBuffer;
|
||||
unsigned long m_nG7FrameBufferSize;
|
||||
|
||||
audio_buffer *m_audio_buffer_;
|
||||
//------
|
||||
InAudioInfo m_inAudioInfo;
|
||||
|
||||
IDecodeToPcm* m_pDecodeToPcm;
|
||||
PcmToAac* m_pPCMToAAC;
|
||||
};
|
||||
|
||||
#endif /* MtAACEncoder_H */
|
||||
|
34
external/libfaac/MtAACEncoderAPI.cpp
vendored
Normal file
34
external/libfaac/MtAACEncoderAPI.cpp
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
#include "MtAACEncoderAPI.h"
|
||||
#include "MtAACEncoder.h"
|
||||
#include "condef.h"
|
||||
|
||||
Mt_API MtAACEncoder_Handle Mt_APICALL Mt_AACEncoder_Init(InitParam initPar)
|
||||
{
|
||||
G7ToAac *encoder = new G7ToAac();
|
||||
InAudioInfo info(initPar );
|
||||
bool ret = encoder->init(info);
|
||||
if (!ret)
|
||||
{
|
||||
SAFE_DELETE_OBJ(encoder);
|
||||
}
|
||||
return encoder;
|
||||
}
|
||||
|
||||
Mt_API int Mt_APICALL Mt_AACEncoder_Encode(MtAACEncoder_Handle handle, unsigned char* inbuf, unsigned int inlen, unsigned char* outbuf, unsigned int* outlen)
|
||||
{
|
||||
if(handle == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return ((G7ToAac*)handle)->aac_encode(inbuf, inlen, outbuf, outlen);
|
||||
}
|
||||
|
||||
Mt_API void Mt_APICALL Mt_AACEncoder_Release(MtAACEncoder_Handle handle)
|
||||
{
|
||||
if(handle != NULL)
|
||||
{
|
||||
delete ((G7ToAac*)handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
75
external/libfaac/MtAACEncoderAPI.h
vendored
Normal file
75
external/libfaac/MtAACEncoderAPI.h
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
|
||||
#ifndef MtAACEncoder_API_H
|
||||
#define MtAACEncoder_API_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#define Mt_API __declspec(dllexport)
|
||||
#define Mt_APICALL __stdcall
|
||||
#else
|
||||
#define Mt_API
|
||||
#define Mt_APICALL
|
||||
#endif
|
||||
|
||||
#define Mt_Handle void*
|
||||
#define MtAACEncoder_Handle void*
|
||||
|
||||
///* Audio Codec */
|
||||
enum Law
|
||||
{
|
||||
Law_ULaw = 0, /**< U law */
|
||||
Law_ALaw = 1, /**< A law */
|
||||
Law_PCM16 = 2, /**< 16 bit uniform PCM values. 原始 pcm 数据 */
|
||||
Law_G726 = 3 /**< G726 */
|
||||
};
|
||||
|
||||
///* Rate Bits */
|
||||
enum Rate
|
||||
{
|
||||
Rate16kBits=2, /**< 16k bits per second (2 bits per ADPCM sample) */
|
||||
Rate24kBits=3, /**< 24k bits per second (3 bits per ADPCM sample) */
|
||||
Rate32kBits=4, /**< 32k bits per second (4 bits per ADPCM sample) */
|
||||
Rate40kBits=5 /**< 40k bits per second (5 bits per ADPCM sample) */
|
||||
};
|
||||
|
||||
typedef struct _g711param
|
||||
{
|
||||
;
|
||||
}G711Param;
|
||||
|
||||
typedef struct _g726param
|
||||
{
|
||||
unsigned char ucRateBits;//Rate16kBits Rate24kBits Rate32kBits Rate40kBits
|
||||
}G726Param;
|
||||
|
||||
typedef struct _initParam
|
||||
{
|
||||
unsigned char ucAudioCodec; // Law_uLaw Law_ALaw Law_PCM16 Law_G726
|
||||
unsigned char ucAudioChannel; //1
|
||||
unsigned int u32AudioSamplerate; //8000
|
||||
unsigned int u32PCMBitSize; //16
|
||||
union
|
||||
{
|
||||
G711Param g711param;
|
||||
G726Param g726param;
|
||||
};
|
||||
|
||||
}InitParam;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
/* 创建AAC Encoder 返回为句柄值 */
|
||||
Mt_API MtAACEncoder_Handle Mt_APICALL Mt_AACEncoder_Init(InitParam initPar);
|
||||
|
||||
/* 输入编码数据,返回编码后数据 */
|
||||
Mt_API int Mt_APICALL Mt_AACEncoder_Encode(MtAACEncoder_Handle handle, unsigned char* inbuf, unsigned int inlen, unsigned char* outbuf, unsigned int* outlen);
|
||||
|
||||
/* 释放AAC Encoder */
|
||||
Mt_API void Mt_APICALL Mt_AACEncoder_Release(MtAACEncoder_Handle handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MtAACEncoder_API_H */
|
106
external/libfaac/MtDSSBuffers.cpp
vendored
Normal file
106
external/libfaac/MtDSSBuffers.cpp
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
#include "MtDSSBuffers.h"
|
||||
|
||||
int init_buffers(buffers_t * bufs, int bufsize, int bufnum)
|
||||
{
|
||||
int i;
|
||||
bufs->rear = 0;
|
||||
bufs->front = 0;
|
||||
if(bufnum > MAX_BUF_NUM)
|
||||
{
|
||||
bufs->bufnum = MAX_BUF_NUM;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufs->bufnum = bufnum;
|
||||
}
|
||||
for(i = 0; i < bufs->bufnum; i++)
|
||||
{
|
||||
bufs->buf[i].length = 0;
|
||||
bufs->buf[i].start = (char *) calloc(1, bufsize);
|
||||
bufs->buf[i].frame_type = -1;
|
||||
bufs->buf[i].channel = -1;
|
||||
bufs->buf[i].frame_index = 0;
|
||||
if(bufs->buf[i].start == NULL)
|
||||
return -1;
|
||||
}
|
||||
#ifdef WIN32
|
||||
InitializeCriticalSection(&(bufs->cs));
|
||||
#else
|
||||
InitializeCriticalSection(&(bufs->cs), NULL);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int free_buffers(buffers_t* bufs)
|
||||
{
|
||||
for(int i = 0; i < bufs->bufnum; i++)
|
||||
{
|
||||
if(bufs->buf[i].start != NULL)
|
||||
free(bufs->buf[i].start);
|
||||
}
|
||||
bufs->pOnVideoData = NULL;
|
||||
DeleteCriticalSection(&(bufs->cs));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int buffers_get_data(void *data, unsigned int *length, buffers_t * bufs, int *type,
|
||||
int *channel, int *frame_index)
|
||||
{
|
||||
int res = -1;
|
||||
EnterCriticalSection(&(bufs->cs));
|
||||
if(bufs->front != bufs->rear)
|
||||
{
|
||||
res = *length = bufs->buf[bufs->front].length;
|
||||
memcpy(data, bufs->buf[bufs->front].start, *length);
|
||||
*type = bufs->buf[bufs->front].frame_type;
|
||||
*channel = bufs->buf[bufs->front].channel;
|
||||
*frame_index = bufs->buf[bufs->front].frame_index;
|
||||
bufs->front = (bufs->front + 1) % bufs->bufnum;
|
||||
//res = 1;
|
||||
}
|
||||
LeaveCriticalSection(&(bufs->cs));
|
||||
return res;
|
||||
}
|
||||
|
||||
int buffers_put_data(void *data, unsigned int length, buffers_t * bufs, int type,
|
||||
int channel, int frame_index)
|
||||
{
|
||||
int res = 0;
|
||||
EnterCriticalSection(&(bufs->cs));
|
||||
|
||||
if(((bufs->rear + 1) % bufs->bufnum) == bufs->front)
|
||||
{
|
||||
res = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufs->buf[bufs->rear].length = length;
|
||||
bufs->buf[bufs->rear].frame_type = type;
|
||||
bufs->buf[bufs->rear].channel = channel;
|
||||
bufs->buf[bufs->rear].frame_index = frame_index;
|
||||
if(length < iBufLen)
|
||||
{
|
||||
memcpy(bufs->buf[bufs->rear].start, data, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
//WriteSystemLog("DataRecv.log", "Frame is too large");
|
||||
printf("Frame is too large, length=%d\r\n", length);
|
||||
}
|
||||
bufs->rear = (bufs->rear + 1) % bufs->bufnum;
|
||||
res = 1;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&(bufs->cs));
|
||||
return res;
|
||||
}
|
||||
|
||||
void buffers_clear_data(buffers_t * bufs)
|
||||
{
|
||||
EnterCriticalSection(&(bufs->cs));
|
||||
bufs->rear = 0;
|
||||
bufs->front = 0;
|
||||
LeaveCriticalSection(&(bufs->cs));
|
||||
}
|
||||
|
||||
|
170
external/libfaac/MtDSSBuffers.h
vendored
Normal file
170
external/libfaac/MtDSSBuffers.h
vendored
Normal file
|
@ -0,0 +1,170 @@
|
|||
|
||||
#ifndef _EasyDSSBuffers_H_
|
||||
#define _EasyDSSBuffers_H_
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <guiddef.h>
|
||||
#include <time.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <list>
|
||||
|
||||
#include <errno.h>
|
||||
#if (defined(_WIN32)) //windows
|
||||
//#define WIN32
|
||||
#ifndef DLL_EXPORT
|
||||
#define JD_API extern "C"__declspec(dllimport)
|
||||
#else
|
||||
#define JD_API extern "C"__declspec(dllexport)
|
||||
#endif
|
||||
#elif defined(__linux__) //linux
|
||||
#define __stdcall
|
||||
#define CALLBACK
|
||||
#define JD_API extern "C"
|
||||
#define WINAPI
|
||||
typedef int HANDLE;
|
||||
typedef int HWND;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define PFRAME 0x00
|
||||
#define IFRAME 0x01
|
||||
|
||||
const int iBufLen = 1024 * 128;
|
||||
const int iRecvBufLen = iBufLen * 2;
|
||||
const int iMaxParamterNum = 128;
|
||||
const int iBufNum = 10;
|
||||
const int MAX_BUF_NUM = 50;
|
||||
const int iCharBufLen = 64;
|
||||
const char BoundTag[] = "\r\n"; //帧间隔标识
|
||||
const int BoundTagLen = sizeof (BoundTag) - 1; //帧间隔标识长度
|
||||
//const char IFrameTag[] = "HISI264I";//录像I帧标志
|
||||
//const char PFrameTag[] = "HISI264P";//录像P帧标志
|
||||
//const int FrameTagLen = sizeof(IFrameTag) - 1;// 录像帧标志长度
|
||||
|
||||
const int MaxWaitTime = 3000; //超时时间
|
||||
const int MaxCameraNum = 24; //最大摄像机数量
|
||||
|
||||
const int AUDIO_BUFFER_SIZE = 960; //定义播放的每一片缓冲都是800个字节
|
||||
const int MAX_AUDIO_BUF = 4; //播放缓冲的通知索引
|
||||
const int BUFFERNOTIFYSIZE = AUDIO_BUFFER_SIZE;/*8192*//*192000*/ //缓冲通知位置的大小,请参见DirectSound应用程序开发快速入门
|
||||
const int SAMPLE_RATE = 8000;/*44100*/ //pcm 的采样率 8k
|
||||
const int N_CHANNEL = 1;/*2*/ //PCM 声道数 单通道
|
||||
const int BITS_PER_SAMPLE = 16; //每个采样点的比特数
|
||||
const int CHANNEL = 1;
|
||||
const int SAMPLES_PER_SECOND = 8000;
|
||||
const int SIZE_AUDIO_FRAME = 960;
|
||||
|
||||
#ifdef WIN32
|
||||
const GUID GUID_YUY2 = {0xc68e1552, 0x4a3f, 0x4706,
|
||||
{0xb2, 0xd4, 0x83, 0x41, 0x4f, 0x15, 0xdc, 0xcc}};
|
||||
//typedef char int8_t;
|
||||
//typedef unsigned char uint8_t;
|
||||
//typedef short int16_t;
|
||||
//typedef unsigned short uint16_t;
|
||||
//typedef int int32_t;
|
||||
//typedef unsigned int uint32_t;
|
||||
//typedef __int64 int64_t;
|
||||
//typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
typedef pthread_mutex_t CRITICAL_SECTION;
|
||||
#define InitializeCriticalSection pthread_mutex_init
|
||||
#define DeleteCriticalSection pthread_mutex_destroy
|
||||
#define EnterCriticalSection pthread_mutex_lock
|
||||
#define LeaveCriticalSection pthread_mutex_unlock
|
||||
//typedef void* LPVOID;
|
||||
//typedef unsigned long DWORD;
|
||||
//#define CloseHandle close
|
||||
#define Sleep(x) usleep(x*1000)
|
||||
//#define closesocket close
|
||||
//#define TRUE true
|
||||
//#define FALSE false
|
||||
//typedef bool BOOL;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
pthread_mutex_t mtx;
|
||||
pthread_cond_t cond;
|
||||
bool manual_reset;
|
||||
bool signaled;
|
||||
} THANDLE, *PHANDLE;
|
||||
|
||||
#define INFINITE 0xFFFFFFFF
|
||||
#define WAIT_TIMEOUT 0x00000102L
|
||||
#define WAIT_OBJECT_0 0
|
||||
#endif
|
||||
|
||||
#ifndef TRACE
|
||||
#define TRACE printf
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\brief H264码流回调函数指针
|
||||
\param iPlayHandle 播放句柄
|
||||
\param sData 数据缓冲区
|
||||
\param iLen 数据长度
|
||||
\param iDataType 数据类型 0 - 实时数据流, 1 - 录像数据流, 2 - 本地采集的音频流, 3 - 设备发过来的音频流
|
||||
*/
|
||||
typedef void(CALLBACK* fVideoDataCallBack)(int iPlayHandle, char* sData, int iLen, int iDataType, void* pUserData);
|
||||
|
||||
/*!
|
||||
\brief 告警信息回调函数指针
|
||||
\param pAlarmInfo 告警信息T_JD_AlarmInfo结构体指针
|
||||
\param pUserData 用户数据
|
||||
*/
|
||||
typedef void(CALLBACK* fMessageCallBack)(void* pAlarmInfo, void* pUserData);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *start;
|
||||
size_t length;
|
||||
int frame_type;
|
||||
int frame_index;
|
||||
int channel;
|
||||
} buffer_t;
|
||||
|
||||
typedef struct _buffers_t
|
||||
{
|
||||
int rear;
|
||||
int front;
|
||||
int bufnum;
|
||||
int fps;
|
||||
CRITICAL_SECTION cs;
|
||||
buffer_t buf[MAX_BUF_NUM];
|
||||
fVideoDataCallBack pOnVideoData; // 数据回调函数指针
|
||||
void* pUserData; //回调函数用户数据
|
||||
|
||||
_buffers_t()
|
||||
{
|
||||
pOnVideoData = NULL;
|
||||
pUserData = NULL;
|
||||
}
|
||||
|
||||
} buffers_t;
|
||||
|
||||
int init_buffers(buffers_t * bufs, int bufsize, int bufnum);
|
||||
|
||||
int free_buffers(buffers_t *bufs);
|
||||
|
||||
int buffers_get_data(void *data, unsigned int *length, buffers_t * bufs, int *type, int *channel, int *frame_index);
|
||||
|
||||
int buffers_put_data(void *data, unsigned int length, buffers_t * bufs, int type, int channel, int frame_index);
|
||||
|
||||
void buffers_clear_data(buffers_t * bufs);
|
||||
|
||||
#endif
|
78
external/libfaac/PcmToAac.cpp
vendored
Normal file
78
external/libfaac/PcmToAac.cpp
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
|
||||
#include "PcmToAac.h"
|
||||
|
||||
#include "outDebug.h"
|
||||
|
||||
PcmToAac::PcmToAac(void)
|
||||
{
|
||||
m_nInputSamples=0;
|
||||
m_nMaxOutputBytes=0;
|
||||
m_nPCMBitSize = 16;
|
||||
}
|
||||
|
||||
|
||||
PcmToAac::~PcmToAac(void)
|
||||
{
|
||||
if (NULL != hEncoder)
|
||||
{
|
||||
/*Close FAAC engine*/
|
||||
faacEncClose(hEncoder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool PcmToAac::Init(InAudioInfo* info)
|
||||
{
|
||||
unsigned int objectType = LOW;
|
||||
unsigned int mpegVersion = MPEG2;
|
||||
static unsigned int useTns = 0; //#define DEFAULT_TNS 0
|
||||
|
||||
//TODO: config this
|
||||
unsigned int nChannels = /*1*/info->Channel();
|
||||
|
||||
m_nPCMBitSize = /*16*/ info->PCMBitSize();
|
||||
unsigned long nInputSamples = 0;
|
||||
unsigned long nSampleRate = /*8000*/info->Samplerate();
|
||||
unsigned long nMaxOutputBytes = 0;
|
||||
|
||||
|
||||
/*open FAAC engine*/
|
||||
hEncoder = faacEncOpen(nSampleRate, nChannels, &nInputSamples, &nMaxOutputBytes);
|
||||
if (hEncoder == NULL)
|
||||
{
|
||||
if(AAC_DEBUG) printf("%s:[%d] failed to call faacEncOpen !\n", __FUNCTION__, __LINE__);
|
||||
//return -1;
|
||||
return false;
|
||||
}
|
||||
m_nInputSamples = nInputSamples;
|
||||
m_nMaxOutputBytes = nMaxOutputBytes;
|
||||
|
||||
|
||||
/*get current encoding configuration*/
|
||||
pConfiguration = faacEncGetCurrentConfiguration(hEncoder);
|
||||
pConfiguration->inputFormat = FAAC_INPUT_16BIT;
|
||||
|
||||
/*0 - raw; 1 - ADTS*/
|
||||
pConfiguration->outputFormat = 1;
|
||||
pConfiguration->useTns = useTns;
|
||||
pConfiguration->aacObjectType = objectType;
|
||||
pConfiguration->mpegVersion = mpegVersion;
|
||||
|
||||
/*set encoding configuretion*/
|
||||
faacEncSetConfiguration(hEncoder, pConfiguration);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int PcmToAac::Encode(int32_t * pbPCMBuffer, unsigned int nPCMBufferSize, unsigned char * pbAACBuffer, unsigned int nMaxOutputBytes)
|
||||
{
|
||||
unsigned int nPCMBitSize = GetPCMBitSize();
|
||||
|
||||
|
||||
unsigned int nInputSamples = (nPCMBufferSize / (nPCMBitSize / 8));
|
||||
if(AAC_DEBUG) printf("%s:[%d] G711A -> PCM faacEncEncode....\n", __FUNCTION__, __LINE__);
|
||||
int nRet = faacEncEncode(hEncoder, (int*) pbPCMBuffer, nInputSamples, pbAACBuffer, nMaxOutputBytes);
|
||||
if(AAC_DEBUG) printf("%s:[%d] G711A -> PCM faacEncEncode\n", __FUNCTION__, __LINE__);
|
||||
|
||||
return nRet;
|
||||
}
|
51
external/libfaac/PcmToAac.h
vendored
Normal file
51
external/libfaac/PcmToAac.h
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "IDecodeToPcm.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <faac.h>
|
||||
}
|
||||
|
||||
class PcmToAac
|
||||
{
|
||||
public:
|
||||
PcmToAac(void);
|
||||
~PcmToAac(void);
|
||||
public:
|
||||
bool Init(InAudioInfo* info);
|
||||
int Encode(int32_t * inputBuffer, unsigned int samplesInput, unsigned char *outputBuffer, unsigned int bufferSize);
|
||||
public:
|
||||
unsigned int GetPCMBitSize()
|
||||
{
|
||||
return m_nPCMBitSize;
|
||||
}
|
||||
unsigned int GetInputSamples()
|
||||
{
|
||||
return m_nInputSamples;
|
||||
}
|
||||
unsigned int GetMaxOutputBytes()
|
||||
{
|
||||
return m_nMaxOutputBytes;
|
||||
}
|
||||
unsigned int GetPCMBufferSize()
|
||||
{
|
||||
return (m_nInputSamples * (m_nPCMBitSize / 8));
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
faacEncHandle hEncoder;
|
||||
faacEncConfigurationPtr pConfiguration;
|
||||
|
||||
unsigned int m_nPCMBitSize /*= 16*/;
|
||||
|
||||
unsigned long m_nInputSamples /*= 0*/;
|
||||
|
||||
unsigned long m_nMaxOutputBytes /*= 0*/;
|
||||
};
|
||||
|
56
external/libfaac/audio_buffer.cpp
vendored
Normal file
56
external/libfaac/audio_buffer.cpp
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
#include "audio_buffer.h"
|
||||
#include "MtDSSBuffers.h"
|
||||
#include "outDebug.h"
|
||||
|
||||
|
||||
audio_buffer::audio_buffer()
|
||||
{
|
||||
data_ = new unsigned char[iBufLen];
|
||||
len_ = 0;
|
||||
}
|
||||
|
||||
audio_buffer::~audio_buffer()
|
||||
{
|
||||
delete []data_;
|
||||
}
|
||||
|
||||
int audio_buffer::write_data(void* data, int len)
|
||||
{
|
||||
if (iBufLen - len_ < len)
|
||||
{
|
||||
if(AAC_DEBUG) printf("audio_buffer full\n");
|
||||
return -1;
|
||||
}
|
||||
if (len > 0)
|
||||
{
|
||||
memcpy(data_ + len_, data, len);
|
||||
len_ += len;
|
||||
return len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int audio_buffer::get_data(unsigned char* dest, int how_you_want)
|
||||
{
|
||||
if (len_ == 0 || len_ < how_you_want)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(dest, data_, how_you_want);
|
||||
memmove(data_, data_ + how_you_want, len_ - how_you_want);
|
||||
len_ -= how_you_want;
|
||||
return how_you_want;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char* audio_buffer::get_writable_ptr()
|
||||
{
|
||||
return data_ + len_;
|
||||
}
|
||||
|
||||
void audio_buffer::update_data_len(int len)
|
||||
{
|
||||
len_ += len;
|
||||
}
|
21
external/libfaac/audio_buffer.h
vendored
Normal file
21
external/libfaac/audio_buffer.h
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
class audio_buffer
|
||||
{
|
||||
public:
|
||||
audio_buffer(void);
|
||||
~audio_buffer(void);
|
||||
|
||||
int write_data(void *data, int len);
|
||||
|
||||
int get_data(unsigned char *dest, int how_you_want);
|
||||
|
||||
void update_data_len(int len);
|
||||
|
||||
unsigned char *get_writable_ptr();
|
||||
|
||||
private:
|
||||
unsigned char *data_;
|
||||
int len_;
|
||||
};
|
||||
|
11
external/libfaac/condef.h
vendored
Normal file
11
external/libfaac/condef.h
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef _CONDEF_H
|
||||
#define _CONDEF_H
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define SAFE_DELETE_OBJ(OBJ) {if(NULL!=OBJ){delete OBJ;OBJ=NULL;}}
|
||||
#define SAFE_FREE_BUF(OBJ) {if(NULL!=OBJ){free(OBJ);OBJ=NULL;}}
|
||||
|
||||
#endif
|
99
external/libfaac/faac.h
vendored
Normal file
99
external/libfaac/faac.h
vendored
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: faac.h,v 1.36 2009/01/25 18:50:32 menno Exp $
|
||||
*/
|
||||
|
||||
#ifndef _FAAC_H_
|
||||
#define _FAAC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
# ifndef FAACAPI
|
||||
# define FAACAPI __stdcall
|
||||
# endif
|
||||
#else
|
||||
# ifndef FAACAPI
|
||||
# define FAACAPI
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef struct {
|
||||
void *ptr;
|
||||
char *name;
|
||||
}
|
||||
psymodellist_t;
|
||||
|
||||
#include "faaccfg.h"
|
||||
|
||||
|
||||
typedef void *faacEncHandle;
|
||||
|
||||
#ifndef HAVE_INT32_T
|
||||
typedef signed int int32_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
Allows an application to get FAAC version info. This is intended
|
||||
purely for informative purposes.
|
||||
|
||||
Returns FAAC_CFG_VERSION.
|
||||
*/
|
||||
int FAACAPI faacEncGetVersion(char **faac_id_string,
|
||||
char **faac_copyright_string);
|
||||
|
||||
|
||||
faacEncConfigurationPtr FAACAPI
|
||||
faacEncGetCurrentConfiguration(faacEncHandle hEncoder);
|
||||
|
||||
|
||||
int FAACAPI faacEncSetConfiguration(faacEncHandle hEncoder,
|
||||
faacEncConfigurationPtr config);
|
||||
|
||||
|
||||
faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate,
|
||||
unsigned int numChannels,
|
||||
unsigned long *inputSamples,
|
||||
unsigned long *maxOutputBytes);
|
||||
|
||||
|
||||
int FAACAPI faacEncGetDecoderSpecificInfo(faacEncHandle hEncoder, unsigned char **ppBuffer,
|
||||
unsigned long *pSizeOfDecoderSpecificInfo);
|
||||
|
||||
|
||||
int FAACAPI faacEncEncode(faacEncHandle hEncoder, int32_t * inputBuffer, unsigned int samplesInput,
|
||||
unsigned char *outputBuffer,
|
||||
unsigned int bufferSize);
|
||||
|
||||
|
||||
int FAACAPI faacEncClose(faacEncHandle hEncoder);
|
||||
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _FAAC_H_ */
|
122
external/libfaac/faaccfg.h
vendored
Normal file
122
external/libfaac/faaccfg.h
vendored
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: faaccfg.h,v 1.3 2004/07/04 12:12:05 corrados Exp $
|
||||
*/
|
||||
|
||||
#ifndef _FAACCFG_H_
|
||||
#define _FAACCFG_H_
|
||||
|
||||
#define FAAC_CFG_VERSION 104
|
||||
|
||||
/* MPEG ID's */
|
||||
#define MPEG2 1
|
||||
#define MPEG4 0
|
||||
|
||||
/* AAC object types */
|
||||
#define MAIN 1
|
||||
#define LOW 2
|
||||
#define SSR 3
|
||||
#define LTP 4
|
||||
|
||||
/* Input Formats */
|
||||
#define FAAC_INPUT_NULL 0
|
||||
#define FAAC_INPUT_16BIT 1
|
||||
#define FAAC_INPUT_24BIT 2
|
||||
#define FAAC_INPUT_32BIT 3
|
||||
#define FAAC_INPUT_FLOAT 4
|
||||
|
||||
#define SHORTCTL_NORMAL 0
|
||||
#define SHORTCTL_NOSHORT 1
|
||||
#define SHORTCTL_NOLONG 2
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct faacEncConfiguration
|
||||
{
|
||||
/* config version */
|
||||
int version;
|
||||
|
||||
/* library version */
|
||||
char *name;
|
||||
|
||||
/* copyright string */
|
||||
char *copyright;
|
||||
|
||||
/* MPEG version, 2 or 4 */
|
||||
unsigned int mpegVersion;
|
||||
|
||||
/* AAC object type */
|
||||
unsigned int aacObjectType;
|
||||
|
||||
/* Allow mid/side coding */
|
||||
unsigned int allowMidside;
|
||||
|
||||
/* Use one of the channels as LFE channel */
|
||||
unsigned int useLfe;
|
||||
|
||||
/* Use Temporal Noise Shaping */
|
||||
unsigned int useTns;
|
||||
|
||||
/* bitrate / channel of AAC file */
|
||||
unsigned long bitRate;
|
||||
|
||||
/* AAC file frequency bandwidth */
|
||||
unsigned int bandWidth;
|
||||
|
||||
/* Quantizer quality */
|
||||
unsigned long quantqual;
|
||||
|
||||
/* Bitstream output format (0 = Raw; 1 = ADTS) */
|
||||
unsigned int outputFormat;
|
||||
|
||||
/* psychoacoustic model list */
|
||||
psymodellist_t *psymodellist;
|
||||
|
||||
/* selected index in psymodellist */
|
||||
unsigned int psymodelidx;
|
||||
|
||||
/*
|
||||
PCM Sample Input Format
|
||||
0 FAAC_INPUT_NULL invalid, signifies a misconfigured config
|
||||
1 FAAC_INPUT_16BIT native endian 16bit
|
||||
2 FAAC_INPUT_24BIT native endian 24bit in 24 bits (not implemented)
|
||||
3 FAAC_INPUT_32BIT native endian 24bit in 32 bits (DEFAULT)
|
||||
4 FAAC_INPUT_FLOAT 32bit floating point
|
||||
*/
|
||||
unsigned int inputFormat;
|
||||
|
||||
/* block type enforcing (SHORTCTL_NORMAL/SHORTCTL_NOSHORT/SHORTCTL_NOLONG) */
|
||||
int shortctl;
|
||||
|
||||
/*
|
||||
Channel Remapping
|
||||
|
||||
Default 0, 1, 2, 3 ... 63 (64 is MAX_CHANNELS in coder.h)
|
||||
|
||||
WAVE 4.0 2, 0, 1, 3
|
||||
WAVE 5.0 2, 0, 1, 3, 4
|
||||
WAVE 5.1 2, 0, 1, 4, 5, 3
|
||||
AIFF 5.1 2, 0, 3, 1, 4, 5
|
||||
*/
|
||||
int channel_map[64];
|
||||
|
||||
} faacEncConfiguration, *faacEncConfigurationPtr;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif /* _FAACCFG_H_ */
|
306
external/libfaac/g711.cpp
vendored
Normal file
306
external/libfaac/g711.cpp
vendored
Normal file
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
* g711.c
|
||||
*
|
||||
* u-law, A-law and linear PCM conversions.
|
||||
*/
|
||||
|
||||
//#include "stdafx.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "g711.h"
|
||||
|
||||
#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
|
||||
#define QUANT_MASK (0xf) /* Quantization field mask. */
|
||||
#define NSEGS (8) /* Number of A-law segments. */
|
||||
#define SEG_SHIFT (4) /* Left shift for segment number. */
|
||||
#define SEG_MASK (0x70) /* Segment field mask. */
|
||||
|
||||
static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,
|
||||
0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
|
||||
|
||||
/* copy from CCITT G.711 specifications */
|
||||
unsigned char _u2a[128] = { /* u- to A-law conversions */
|
||||
1, 1, 2, 2, 3, 3, 4, 4,
|
||||
5, 5, 6, 6, 7, 7, 8, 8,
|
||||
9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 29, 31, 33, 34, 35, 36,
|
||||
37, 38, 39, 40, 41, 42, 43, 44,
|
||||
46, 48, 49, 50, 51, 52, 53, 54,
|
||||
55, 56, 57, 58, 59, 60, 61, 62,
|
||||
64, 65, 66, 67, 68, 69, 70, 71,
|
||||
72, 73, 74, 75, 76, 77, 78, 79,
|
||||
81, 82, 83, 84, 85, 86, 87, 88,
|
||||
89, 90, 91, 92, 93, 94, 95, 96,
|
||||
97, 98, 99, 100, 101, 102, 103, 104,
|
||||
105, 106, 107, 108, 109, 110, 111, 112,
|
||||
113, 114, 115, 116, 117, 118, 119, 120,
|
||||
121, 122, 123, 124, 125, 126, 127, 128};
|
||||
|
||||
unsigned char _a2u[128] = { /* A- to u-law conversions */
|
||||
1, 3, 5, 7, 9, 11, 13, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 32, 33, 33, 34, 34, 35, 35,
|
||||
36, 37, 38, 39, 40, 41, 42, 43,
|
||||
44, 45, 46, 47, 48, 48, 49, 49,
|
||||
50, 51, 52, 53, 54, 55, 56, 57,
|
||||
58, 59, 60, 61, 62, 63, 64, 64,
|
||||
65, 66, 67, 68, 69, 70, 71, 72,
|
||||
73, 74, 75, 76, 77, 78, 79, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87,
|
||||
88, 89, 90, 91, 92, 93, 94, 95,
|
||||
96, 97, 98, 99, 100, 101, 102, 103,
|
||||
104, 105, 106, 107, 108, 109, 110, 111,
|
||||
112, 113, 114, 115, 116, 117, 118, 119,
|
||||
120, 121, 122, 123, 124, 125, 126, 127};
|
||||
|
||||
static int
|
||||
search(
|
||||
int val,
|
||||
short *table,
|
||||
int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (val <= *table++)
|
||||
return (i);
|
||||
}
|
||||
return (size);
|
||||
}
|
||||
|
||||
/*
|
||||
* linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
|
||||
*
|
||||
* linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
|
||||
*
|
||||
* Linear Input Code Compressed Code
|
||||
* ------------------------ ---------------
|
||||
* 0000000wxyza 000wxyz
|
||||
* 0000001wxyza 001wxyz
|
||||
* 000001wxyzab 010wxyz
|
||||
* 00001wxyzabc 011wxyz
|
||||
* 0001wxyzabcd 100wxyz
|
||||
* 001wxyzabcde 101wxyz
|
||||
* 01wxyzabcdef 110wxyz
|
||||
* 1wxyzabcdefg 111wxyz
|
||||
*
|
||||
* For further information see John C. Bellamy's Digital Telephony, 1982,
|
||||
* John Wiley & Sons, pps 98-111 and 472-476.
|
||||
*/
|
||||
unsigned char
|
||||
linear2alaw(
|
||||
int pcm_val) /* 2's complement (16-bit range) */
|
||||
{
|
||||
int mask;
|
||||
int seg;
|
||||
unsigned char aval;
|
||||
|
||||
if (pcm_val >= 0) {
|
||||
mask = 0xD5; /* sign (7th) bit = 1 */
|
||||
} else {
|
||||
mask = 0x55; /* sign bit = 0 */
|
||||
pcm_val = -pcm_val - 8;
|
||||
}
|
||||
|
||||
/* Convert the scaled magnitude to segment number. */
|
||||
seg = search(pcm_val, seg_end, 8);
|
||||
|
||||
/* Combine the sign, segment, and quantization bits. */
|
||||
|
||||
if (seg >= 8) /* out of range, return maximum value. */
|
||||
return (0x7F ^ mask);
|
||||
else {
|
||||
aval = seg << SEG_SHIFT;
|
||||
if (seg < 2)
|
||||
aval |= (pcm_val >> 4) & QUANT_MASK;
|
||||
else
|
||||
aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
|
||||
return (aval ^ mask);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* alaw2linear() - Convert an A-law value to 16-bit linear PCM
|
||||
*
|
||||
*/
|
||||
int
|
||||
alaw2linear(
|
||||
unsigned char a_val)
|
||||
{
|
||||
int t;
|
||||
int seg;
|
||||
|
||||
a_val ^= 0x55;
|
||||
|
||||
t = (a_val & QUANT_MASK) << 4;
|
||||
seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
|
||||
switch (seg) {
|
||||
case 0:
|
||||
t += 8;
|
||||
break;
|
||||
case 1:
|
||||
t += 0x108;
|
||||
break;
|
||||
default:
|
||||
t += 0x108;
|
||||
t <<= seg - 1;
|
||||
}
|
||||
return ((a_val & SIGN_BIT) ? t : -t);
|
||||
}
|
||||
|
||||
#define BIAS (0x84) /* Bias for linear code. */
|
||||
|
||||
/*
|
||||
* linear2ulaw() - Convert a linear PCM value to u-law
|
||||
*
|
||||
* In order to simplify the encoding process, the original linear magnitude
|
||||
* is biased by adding 33 which shifts the encoding range from (0 - 8158) to
|
||||
* (33 - 8191). The result can be seen in the following encoding table:
|
||||
*
|
||||
* Biased Linear Input Code Compressed Code
|
||||
* ------------------------ ---------------
|
||||
* 00000001wxyza 000wxyz
|
||||
* 0000001wxyzab 001wxyz
|
||||
* 000001wxyzabc 010wxyz
|
||||
* 00001wxyzabcd 011wxyz
|
||||
* 0001wxyzabcde 100wxyz
|
||||
* 001wxyzabcdef 101wxyz
|
||||
* 01wxyzabcdefg 110wxyz
|
||||
* 1wxyzabcdefgh 111wxyz
|
||||
*
|
||||
* Each biased linear code has a leading 1 which identifies the segment
|
||||
* number. The value of the segment number is equal to 7 minus the number
|
||||
* of leading 0's. The quantization interval is directly available as the
|
||||
* four bits wxyz. * The trailing bits (a - h) are ignored.
|
||||
*
|
||||
* Ordinarily the complement of the resulting code word is used for
|
||||
* transmission, and so the code word is complemented before it is returned.
|
||||
*
|
||||
* For further information see John C. Bellamy's Digital Telephony, 1982,
|
||||
* John Wiley & Sons, pps 98-111 and 472-476.
|
||||
*/
|
||||
unsigned char
|
||||
linear2ulaw(
|
||||
int pcm_val) /* 2's complement (16-bit range) */
|
||||
{
|
||||
int mask;
|
||||
int seg;
|
||||
unsigned char uval;
|
||||
|
||||
/* Get the sign and the magnitude of the value. */
|
||||
if (pcm_val < 0) {
|
||||
pcm_val = BIAS - pcm_val;
|
||||
mask = 0x7F;
|
||||
} else {
|
||||
pcm_val += BIAS;
|
||||
mask = 0xFF;
|
||||
}
|
||||
|
||||
/* Convert the scaled magnitude to segment number. */
|
||||
seg = search(pcm_val, seg_end, 8);
|
||||
|
||||
/*
|
||||
* Combine the sign, segment, quantization bits;
|
||||
* and complement the code word.
|
||||
*/
|
||||
if (seg >= 8) /* out of range, return maximum value. */
|
||||
return (0x7F ^ mask);
|
||||
else {
|
||||
uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
|
||||
return (uval ^ mask);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* ulaw2linear() - Convert a u-law value to 16-bit linear PCM
|
||||
*
|
||||
* First, a biased linear code is derived from the code word. An unbiased
|
||||
* output can then be obtained by subtracting 33 from the biased code.
|
||||
*
|
||||
* Note that this function expects to be passed the complement of the
|
||||
* original code word. This is in keeping with ISDN conventions.
|
||||
*/
|
||||
int
|
||||
ulaw2linear(
|
||||
unsigned char u_val)
|
||||
{
|
||||
int t;
|
||||
|
||||
/* Complement to obtain normal u-law value. */
|
||||
u_val = ~u_val;
|
||||
|
||||
/*
|
||||
* Extract and bias the quantization bits. Then
|
||||
* shift up by the segment number and subtract out the bias.
|
||||
*/
|
||||
t = ((u_val & QUANT_MASK) << 3) + BIAS;
|
||||
t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
|
||||
|
||||
return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
|
||||
}
|
||||
|
||||
/* A-law to u-law conversion */
|
||||
unsigned char
|
||||
alaw2ulaw(
|
||||
unsigned char aval)
|
||||
{
|
||||
aval &= 0xff;
|
||||
return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
|
||||
(0x7F ^ _a2u[aval ^ 0x55]));
|
||||
}
|
||||
|
||||
/* u-law to A-law conversion */
|
||||
unsigned char
|
||||
ulaw2alaw(
|
||||
unsigned char uval)
|
||||
{
|
||||
uval &= 0xff;
|
||||
return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
|
||||
(0x55 ^ (_u2a[0x7F ^ uval] - 1)));
|
||||
}
|
||||
|
||||
int g711_decode(void *pout_buf, int *pout_len, const void *pin_buf, const int in_len , int type)
|
||||
{
|
||||
int16_t *dst = (int16_t *) pout_buf;
|
||||
uint8_t *src = (uint8_t *) pin_buf;
|
||||
uint32_t i = 0;
|
||||
int Ret = 0;
|
||||
|
||||
if ((NULL == pout_buf) || \
|
||||
(NULL == pout_len) || \
|
||||
(NULL == pin_buf) || \
|
||||
(0 == in_len))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*pout_len < 2 * in_len)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
//---{{{
|
||||
if (TP_ALAW == type)
|
||||
{
|
||||
for (i = 0; i < in_len; i++)
|
||||
{
|
||||
//*(dst++) = alawtos16[*(src++)];
|
||||
*(dst++) = (int16_t)alaw2linear(*(src++));
|
||||
}
|
||||
}else
|
||||
{
|
||||
for (i = 0; i < in_len; i++)
|
||||
{
|
||||
//*(dst++) = alawtos16[*(src++)];
|
||||
*(dst++) = (int16_t)ulaw2linear(*(src++));
|
||||
}
|
||||
}
|
||||
|
||||
//---}}}
|
||||
*pout_len = 2 * in_len;
|
||||
|
||||
Ret = 2 * in_len;
|
||||
return Ret;
|
||||
}
|
24
external/libfaac/g711.h
vendored
Normal file
24
external/libfaac/g711.h
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
|
||||
#ifndef __G_711_H_
|
||||
#define __G_711_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum _e_g711_tp
|
||||
{
|
||||
TP_ALAW, //G711A
|
||||
TP_ULAW //G711U
|
||||
};
|
||||
|
||||
unsigned char linear2alaw(int pcm_val); /* 2's complement (16-bit range) */
|
||||
int alaw2linear(unsigned char a_val);
|
||||
|
||||
unsigned char linear2ulaw(int pcm_val); /* 2's complement (16-bit range) */
|
||||
int ulaw2linear(unsigned char u_val);
|
||||
|
||||
unsigned char alaw2ulaw(unsigned char aval);
|
||||
unsigned char ulaw2alaw(unsigned char uval);
|
||||
|
||||
int g711_decode(void *pout_buf, int *pout_len, const void *pin_buf, const int in_len , int type);
|
||||
|
||||
#endif
|
708
external/libfaac/libfaac/aacquant.c
vendored
Normal file
708
external/libfaac/libfaac/aacquant.c
vendored
Normal file
|
@ -0,0 +1,708 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
* Copyright (C) 2002, 2003 Krzysztof Nikiel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: aacquant.c,v 1.32 2008/03/23 23:00:25 menno Exp $
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "frame.h"
|
||||
#include "aacquant.h"
|
||||
#include "coder.h"
|
||||
#include "huffman.h"
|
||||
#include "psych.h"
|
||||
#include "util.h"
|
||||
|
||||
#define TAKEHIRO_IEEE754_HACK 1
|
||||
|
||||
#define XRPOW_FTOI(src,dest) ((dest) = (int)(src))
|
||||
#define QUANTFAC(rx) adj43[rx]
|
||||
#define ROUNDFAC 0.4054
|
||||
|
||||
static int FixNoise(CoderInfo *coderInfo,
|
||||
const double *xr,
|
||||
double *xr_pow,
|
||||
int *xi,
|
||||
double *xmin,
|
||||
double *pow43,
|
||||
double *adj43);
|
||||
|
||||
static void CalcAllowedDist(CoderInfo *coderInfo, PsyInfo *psyInfo,
|
||||
double *xr, double *xmin, int quality);
|
||||
|
||||
|
||||
void AACQuantizeInit(CoderInfo *coderInfo, unsigned int numChannels,
|
||||
AACQuantCfg *aacquantCfg)
|
||||
{
|
||||
unsigned int channel, i;
|
||||
|
||||
aacquantCfg->pow43 = (double*)AllocMemory(PRECALC_SIZE*sizeof(double));
|
||||
aacquantCfg->adj43 = (double*)AllocMemory(PRECALC_SIZE*sizeof(double));
|
||||
|
||||
aacquantCfg->pow43[0] = 0.0;
|
||||
for(i=1;i<PRECALC_SIZE;i++)
|
||||
aacquantCfg->pow43[i] = pow((double)i, 4.0/3.0);
|
||||
|
||||
#if TAKEHIRO_IEEE754_HACK
|
||||
aacquantCfg->adj43[0] = 0.0;
|
||||
for (i = 1; i < PRECALC_SIZE; i++)
|
||||
aacquantCfg->adj43[i] = i - 0.5 - pow(0.5 * (aacquantCfg->pow43[i - 1] + aacquantCfg->pow43[i]),0.75);
|
||||
#else // !TAKEHIRO_IEEE754_HACK
|
||||
for (i = 0; i < PRECALC_SIZE-1; i++)
|
||||
aacquantCfg->adj43[i] = (i + 1) - pow(0.5 * (aacquantCfg->pow43[i] + aacquantCfg->pow43[i + 1]), 0.75);
|
||||
aacquantCfg->adj43[i] = 0.5;
|
||||
#endif
|
||||
|
||||
for (channel = 0; channel < numChannels; channel++) {
|
||||
coderInfo[channel].requantFreq = (double*)AllocMemory(BLOCK_LEN_LONG*sizeof(double));
|
||||
}
|
||||
}
|
||||
|
||||
void AACQuantizeEnd(CoderInfo *coderInfo, unsigned int numChannels,
|
||||
AACQuantCfg *aacquantCfg)
|
||||
{
|
||||
unsigned int channel;
|
||||
|
||||
if (aacquantCfg->pow43)
|
||||
{
|
||||
FreeMemory(aacquantCfg->pow43);
|
||||
aacquantCfg->pow43 = NULL;
|
||||
}
|
||||
if (aacquantCfg->adj43)
|
||||
{
|
||||
FreeMemory(aacquantCfg->adj43);
|
||||
aacquantCfg->adj43 = NULL;
|
||||
}
|
||||
|
||||
for (channel = 0; channel < numChannels; channel++) {
|
||||
if (coderInfo[channel].requantFreq) FreeMemory(coderInfo[channel].requantFreq);
|
||||
}
|
||||
}
|
||||
|
||||
static void BalanceEnergy(CoderInfo *coderInfo,
|
||||
const double *xr, const int *xi,
|
||||
double *pow43)
|
||||
{
|
||||
const double ifqstep = pow(2.0, 0.25);
|
||||
const double logstep_1 = 1.0 / log(ifqstep);
|
||||
int sb;
|
||||
int nsfb = coderInfo->nr_of_sfb;
|
||||
int start, end;
|
||||
int l;
|
||||
double en0, enq;
|
||||
int shift;
|
||||
|
||||
for (sb = 0; sb < nsfb; sb++)
|
||||
{
|
||||
double qfac_1;
|
||||
|
||||
start = coderInfo->sfb_offset[sb];
|
||||
end = coderInfo->sfb_offset[sb+1];
|
||||
|
||||
qfac_1 = pow(2.0, -0.25*(coderInfo->scale_factor[sb] - coderInfo->global_gain));
|
||||
|
||||
en0 = 0.0;
|
||||
enq = 0.0;
|
||||
for (l = start; l < end; l++)
|
||||
{
|
||||
double xq;
|
||||
|
||||
if (!sb && !xi[l])
|
||||
continue;
|
||||
|
||||
xq = pow43[xi[l]];
|
||||
|
||||
en0 += xr[l] * xr[l];
|
||||
enq += xq * xq;
|
||||
}
|
||||
|
||||
if (enq == 0.0)
|
||||
continue;
|
||||
|
||||
enq *= qfac_1 * qfac_1;
|
||||
|
||||
shift = (int)(log(sqrt(enq / en0)) * logstep_1 + 1000.5);
|
||||
shift -= 1000;
|
||||
|
||||
shift += coderInfo->scale_factor[sb];
|
||||
coderInfo->scale_factor[sb] = shift;
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateRequant(CoderInfo *coderInfo, int *xi,
|
||||
double *pow43)
|
||||
{
|
||||
double *requant_xr = coderInfo->requantFreq;
|
||||
int sb;
|
||||
int i;
|
||||
|
||||
for (sb = 0; sb < coderInfo->nr_of_sfb; sb++)
|
||||
{
|
||||
double invQuantFac =
|
||||
pow(2.0, -0.25*(coderInfo->scale_factor[sb] - coderInfo->global_gain));
|
||||
int start = coderInfo->sfb_offset[sb];
|
||||
int end = coderInfo->sfb_offset[sb + 1];
|
||||
|
||||
for (i = start; i < end; i++)
|
||||
requant_xr[i] = pow43[xi[i]] * invQuantFac;
|
||||
}
|
||||
}
|
||||
|
||||
int AACQuantize(CoderInfo *coderInfo,
|
||||
PsyInfo *psyInfo,
|
||||
ChannelInfo *channelInfo,
|
||||
int *cb_width,
|
||||
int num_cb,
|
||||
double *xr,
|
||||
AACQuantCfg *aacquantCfg)
|
||||
{
|
||||
int sb, i, do_q = 0;
|
||||
int bits = 0, sign;
|
||||
double xr_pow[FRAME_LEN];
|
||||
double xmin[MAX_SCFAC_BANDS];
|
||||
int xi[FRAME_LEN];
|
||||
|
||||
/* Use local copy's */
|
||||
int *scale_factor = coderInfo->scale_factor;
|
||||
|
||||
/* Set all scalefactors to 0 */
|
||||
coderInfo->global_gain = 0;
|
||||
for (sb = 0; sb < coderInfo->nr_of_sfb; sb++)
|
||||
scale_factor[sb] = 0;
|
||||
|
||||
/* Compute xr_pow */
|
||||
for (i = 0; i < FRAME_LEN; i++) {
|
||||
double temp = fabs(xr[i]);
|
||||
xr_pow[i] = sqrt(temp * sqrt(temp));
|
||||
do_q += (temp > 1E-20);
|
||||
}
|
||||
|
||||
if (do_q) {
|
||||
CalcAllowedDist(coderInfo, psyInfo, xr, xmin, aacquantCfg->quality);
|
||||
coderInfo->global_gain = 0;
|
||||
FixNoise(coderInfo, xr, xr_pow, xi, xmin,
|
||||
aacquantCfg->pow43, aacquantCfg->adj43);
|
||||
BalanceEnergy(coderInfo, xr, xi, aacquantCfg->pow43);
|
||||
UpdateRequant(coderInfo, xi, aacquantCfg->pow43);
|
||||
|
||||
for ( i = 0; i < FRAME_LEN; i++ ) {
|
||||
sign = (xr[i] < 0) ? -1 : 1;
|
||||
xi[i] *= sign;
|
||||
coderInfo->requantFreq[i] *= sign;
|
||||
}
|
||||
} else {
|
||||
coderInfo->global_gain = 0;
|
||||
SetMemory(xi, 0, FRAME_LEN*sizeof(int));
|
||||
}
|
||||
|
||||
BitSearch(coderInfo, xi);
|
||||
|
||||
/* offset the difference of common_scalefac and scalefactors by SF_OFFSET */
|
||||
for (i = 0; i < coderInfo->nr_of_sfb; i++) {
|
||||
if ((coderInfo->book_vector[i]!=INTENSITY_HCB)&&(coderInfo->book_vector[i]!=INTENSITY_HCB2)) {
|
||||
scale_factor[i] = coderInfo->global_gain - scale_factor[i] + SF_OFFSET;
|
||||
}
|
||||
}
|
||||
coderInfo->global_gain = scale_factor[0];
|
||||
#if 0
|
||||
printf("global gain: %d\n", coderInfo->global_gain);
|
||||
for (i = 0; i < coderInfo->nr_of_sfb; i++)
|
||||
printf("sf %d: %d\n", i, coderInfo->scale_factor[i]);
|
||||
#endif
|
||||
// clamp to valid diff range
|
||||
{
|
||||
int previous_scale_factor = coderInfo->global_gain;
|
||||
int previous_is_factor = 0;
|
||||
for (i = 0; i < coderInfo->nr_of_sfb; i++) {
|
||||
if ((coderInfo->book_vector[i]==INTENSITY_HCB) ||
|
||||
(coderInfo->book_vector[i]==INTENSITY_HCB2)) {
|
||||
const int diff = scale_factor[i] - previous_is_factor;
|
||||
if (diff < -60) scale_factor[i] = previous_is_factor - 60;
|
||||
else if (diff > 59) scale_factor[i] = previous_is_factor + 59;
|
||||
previous_is_factor = scale_factor[i];
|
||||
// printf("sf %d: %d diff=%d **\n", i, coderInfo->scale_factor[i], diff);
|
||||
} else if (coderInfo->book_vector[i]) {
|
||||
const int diff = scale_factor[i] - previous_scale_factor;
|
||||
if (diff < -60) scale_factor[i] = previous_scale_factor - 60;
|
||||
else if (diff > 59) scale_factor[i] = previous_scale_factor + 59;
|
||||
previous_scale_factor = scale_factor[i];
|
||||
// printf("sf %d: %d diff=%d\n", i, coderInfo->scale_factor[i], diff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* place the codewords and their respective lengths in arrays data[] and len[] respectively */
|
||||
/* there are 'counter' elements in each array, and these are variable length arrays depending on the input */
|
||||
#ifdef DRM
|
||||
coderInfo->iLenReordSpData = 0; /* init length of reordered spectral data */
|
||||
coderInfo->iLenLongestCW = 0; /* init length of longest codeword */
|
||||
coderInfo->cur_cw = 0; /* init codeword counter */
|
||||
#endif
|
||||
coderInfo->spectral_count = 0;
|
||||
sb = 0;
|
||||
for(i = 0; i < coderInfo->nr_of_sfb; i++) {
|
||||
OutputBits(
|
||||
coderInfo,
|
||||
#ifdef DRM
|
||||
&coderInfo->book_vector[i], /* needed for VCB11 */
|
||||
#else
|
||||
coderInfo->book_vector[i],
|
||||
#endif
|
||||
xi,
|
||||
coderInfo->sfb_offset[i],
|
||||
coderInfo->sfb_offset[i+1]-coderInfo->sfb_offset[i]);
|
||||
|
||||
if (coderInfo->book_vector[i])
|
||||
sb = i;
|
||||
}
|
||||
|
||||
// FIXME: Check those max_sfb/nr_of_sfb. Isn't it the same?
|
||||
coderInfo->max_sfb = coderInfo->nr_of_sfb = sb + 1;
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
|
||||
#if TAKEHIRO_IEEE754_HACK
|
||||
|
||||
typedef union {
|
||||
float f;
|
||||
int i;
|
||||
} fi_union;
|
||||
|
||||
#define MAGIC_FLOAT (65536*(128))
|
||||
#define MAGIC_INT 0x4b000000
|
||||
|
||||
#if 0
|
||||
static void Quantize(const double *xp, int *pi, double istep)
|
||||
{
|
||||
int j;
|
||||
fi_union *fi;
|
||||
|
||||
fi = (fi_union *)pi;
|
||||
for (j = FRAME_LEN/4 - 1; j >= 0; --j) {
|
||||
double x0 = istep * xp[0];
|
||||
double x1 = istep * xp[1];
|
||||
double x2 = istep * xp[2];
|
||||
double x3 = istep * xp[3];
|
||||
|
||||
x0 += MAGIC_FLOAT; fi[0].f = x0;
|
||||
x1 += MAGIC_FLOAT; fi[1].f = x1;
|
||||
x2 += MAGIC_FLOAT; fi[2].f = x2;
|
||||
x3 += MAGIC_FLOAT; fi[3].f = x3;
|
||||
|
||||
fi[0].f = x0 + (adj43asm - MAGIC_INT)[fi[0].i];
|
||||
fi[1].f = x1 + (adj43asm - MAGIC_INT)[fi[1].i];
|
||||
fi[2].f = x2 + (adj43asm - MAGIC_INT)[fi[2].i];
|
||||
fi[3].f = x3 + (adj43asm - MAGIC_INT)[fi[3].i];
|
||||
|
||||
fi[0].i -= MAGIC_INT;
|
||||
fi[1].i -= MAGIC_INT;
|
||||
fi[2].i -= MAGIC_INT;
|
||||
fi[3].i -= MAGIC_INT;
|
||||
fi += 4;
|
||||
xp += 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
static void QuantizeBand(const double *xp, int *pi, double istep,
|
||||
int offset, int end, double *adj43)
|
||||
{
|
||||
int j;
|
||||
fi_union *fi;
|
||||
|
||||
fi = (fi_union *)pi;
|
||||
for (j = offset; j < end; j++)
|
||||
{
|
||||
double x0 = istep * xp[j];
|
||||
|
||||
x0 += MAGIC_FLOAT; fi[j].f = (float)x0;
|
||||
fi[j].f = x0 + (adj43 - MAGIC_INT)[fi[j].i];
|
||||
fi[j].i -= MAGIC_INT;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#if 0
|
||||
static void Quantize(const double *xr, int *ix, double istep)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = FRAME_LEN/8; j > 0; --j) {
|
||||
double x1, x2, x3, x4, x5, x6, x7, x8;
|
||||
int rx1, rx2, rx3, rx4, rx5, rx6, rx7, rx8;
|
||||
|
||||
x1 = *xr++ * istep;
|
||||
x2 = *xr++ * istep;
|
||||
XRPOW_FTOI(x1, rx1);
|
||||
x3 = *xr++ * istep;
|
||||
XRPOW_FTOI(x2, rx2);
|
||||
x4 = *xr++ * istep;
|
||||
XRPOW_FTOI(x3, rx3);
|
||||
x5 = *xr++ * istep;
|
||||
XRPOW_FTOI(x4, rx4);
|
||||
x6 = *xr++ * istep;
|
||||
XRPOW_FTOI(x5, rx5);
|
||||
x7 = *xr++ * istep;
|
||||
XRPOW_FTOI(x6, rx6);
|
||||
x8 = *xr++ * istep;
|
||||
XRPOW_FTOI(x7, rx7);
|
||||
x1 += QUANTFAC(rx1);
|
||||
XRPOW_FTOI(x8, rx8);
|
||||
x2 += QUANTFAC(rx2);
|
||||
XRPOW_FTOI(x1,*ix++);
|
||||
x3 += QUANTFAC(rx3);
|
||||
XRPOW_FTOI(x2,*ix++);
|
||||
x4 += QUANTFAC(rx4);
|
||||
XRPOW_FTOI(x3,*ix++);
|
||||
x5 += QUANTFAC(rx5);
|
||||
XRPOW_FTOI(x4,*ix++);
|
||||
x6 += QUANTFAC(rx6);
|
||||
XRPOW_FTOI(x5,*ix++);
|
||||
x7 += QUANTFAC(rx7);
|
||||
XRPOW_FTOI(x6,*ix++);
|
||||
x8 += QUANTFAC(rx8);
|
||||
XRPOW_FTOI(x7,*ix++);
|
||||
XRPOW_FTOI(x8,*ix++);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
static void QuantizeBand(const double *xp, int *ix, double istep,
|
||||
int offset, int end, double *adj43)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = offset; j < end; j++)
|
||||
{
|
||||
double x0 = istep * xp[j];
|
||||
x0 += adj43[(int)x0];
|
||||
ix[j] = (int)x0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void CalcAllowedDist(CoderInfo *coderInfo, PsyInfo *psyInfo,
|
||||
double *xr, double *xmin, int quality)
|
||||
{
|
||||
int sfb, start, end, l;
|
||||
const double globalthr = 132.0 / (double)quality;
|
||||
int last = coderInfo->lastx;
|
||||
int lastsb = 0;
|
||||
int *cb_offset = coderInfo->sfb_offset;
|
||||
int num_cb = coderInfo->nr_of_sfb;
|
||||
double avgenrg = coderInfo->avgenrg;
|
||||
|
||||
for (sfb = 0; sfb < num_cb; sfb++)
|
||||
{
|
||||
if (last > cb_offset[sfb])
|
||||
lastsb = sfb;
|
||||
}
|
||||
|
||||
for (sfb = 0; sfb < num_cb; sfb++)
|
||||
{
|
||||
double thr, tmp;
|
||||
double enrg = 0.0;
|
||||
|
||||
start = cb_offset[sfb];
|
||||
end = cb_offset[sfb + 1];
|
||||
|
||||
if (sfb > lastsb)
|
||||
{
|
||||
xmin[sfb] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (coderInfo->block_type != ONLY_SHORT_WINDOW)
|
||||
{
|
||||
double enmax = -1.0;
|
||||
double lmax;
|
||||
|
||||
lmax = start;
|
||||
for (l = start; l < end; l++)
|
||||
{
|
||||
if (enmax < (xr[l] * xr[l]))
|
||||
{
|
||||
enmax = xr[l] * xr[l];
|
||||
lmax = l;
|
||||
}
|
||||
}
|
||||
|
||||
start = lmax - 2;
|
||||
end = lmax + 3;
|
||||
if (start < 0)
|
||||
start = 0;
|
||||
if (end > last)
|
||||
end = last;
|
||||
}
|
||||
|
||||
for (l = start; l < end; l++)
|
||||
{
|
||||
enrg += xr[l]*xr[l];
|
||||
}
|
||||
|
||||
thr = enrg/((double)(end-start)*avgenrg);
|
||||
thr = pow(thr, 0.1*(lastsb-sfb)/lastsb + 0.3);
|
||||
|
||||
tmp = 1.0 - ((double)start / (double)last);
|
||||
tmp = tmp * tmp * tmp + 0.075;
|
||||
|
||||
thr = 1.0 / (1.4*thr + tmp);
|
||||
|
||||
xmin[sfb] = ((coderInfo->block_type == ONLY_SHORT_WINDOW) ? 0.65 : 1.12)
|
||||
* globalthr * thr;
|
||||
}
|
||||
}
|
||||
|
||||
static int FixNoise(CoderInfo *coderInfo,
|
||||
const double *xr,
|
||||
double *xr_pow,
|
||||
int *xi,
|
||||
double *xmin,
|
||||
double *pow43,
|
||||
double *adj43)
|
||||
{
|
||||
int i, sb;
|
||||
int start, end;
|
||||
double diffvol;
|
||||
double tmp;
|
||||
const double ifqstep = pow(2.0, 0.1875);
|
||||
const double log_ifqstep = 1.0 / log(ifqstep);
|
||||
const double maxstep = 0.05;
|
||||
|
||||
for (sb = 0; sb < coderInfo->nr_of_sfb; sb++)
|
||||
{
|
||||
double sfacfix;
|
||||
double fixstep = 0.25;
|
||||
int sfac;
|
||||
double fac;
|
||||
int dist;
|
||||
double sfacfix0 = 1.0, dist0 = 1e50;
|
||||
double maxx;
|
||||
|
||||
start = coderInfo->sfb_offset[sb];
|
||||
end = coderInfo->sfb_offset[sb+1];
|
||||
|
||||
if (!xmin[sb])
|
||||
goto nullsfb;
|
||||
|
||||
maxx = 0.0;
|
||||
for (i = start; i < end; i++)
|
||||
{
|
||||
if (xr_pow[i] > maxx)
|
||||
maxx = xr_pow[i];
|
||||
}
|
||||
|
||||
//printf("band %d: maxx: %f\n", sb, maxx);
|
||||
if (maxx < 10.0)
|
||||
{
|
||||
nullsfb:
|
||||
for (i = start; i < end; i++)
|
||||
xi[i] = 0;
|
||||
coderInfo->scale_factor[sb] = 10;
|
||||
continue;
|
||||
}
|
||||
|
||||
sfacfix = 1.0 / maxx;
|
||||
sfac = (int)(log(sfacfix) * log_ifqstep - 0.5);
|
||||
for (i = start; i < end; i++)
|
||||
xr_pow[i] *= sfacfix;
|
||||
maxx *= sfacfix;
|
||||
coderInfo->scale_factor[sb] = sfac;
|
||||
QuantizeBand(xr_pow, xi, IPOW20(coderInfo->global_gain), start, end,
|
||||
adj43);
|
||||
//printf("\tsfac: %d\n", sfac);
|
||||
|
||||
calcdist:
|
||||
diffvol = 0.0;
|
||||
for (i = start; i < end; i++)
|
||||
{
|
||||
tmp = xi[i];
|
||||
diffvol += tmp * tmp; // ~x^(3/2)
|
||||
}
|
||||
|
||||
if (diffvol < 1e-6)
|
||||
diffvol = 1e-6;
|
||||
tmp = pow(diffvol / (double)(end - start), -0.666);
|
||||
|
||||
if (fabs(fixstep) > maxstep)
|
||||
{
|
||||
double dd = 0.5*(tmp / xmin[sb] - 1.0);
|
||||
|
||||
if (fabs(dd) < fabs(fixstep))
|
||||
{
|
||||
fixstep = dd;
|
||||
|
||||
if (fabs(fixstep) < maxstep)
|
||||
fixstep = maxstep * ((fixstep > 0) ? 1 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (fixstep > 0)
|
||||
{
|
||||
if (tmp < dist0)
|
||||
{
|
||||
dist0 = tmp;
|
||||
sfacfix0 = sfacfix;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fixstep > .1)
|
||||
fixstep = .1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dist0 = tmp;
|
||||
sfacfix0 = sfacfix;
|
||||
}
|
||||
|
||||
dist = (tmp > xmin[sb]);
|
||||
fac = 0.0;
|
||||
if (fabs(fixstep) >= maxstep)
|
||||
{
|
||||
if ((dist && (fixstep < 0))
|
||||
|| (!dist && (fixstep > 0)))
|
||||
{
|
||||
fixstep = -0.5 * fixstep;
|
||||
}
|
||||
|
||||
fac = 1.0 + fixstep;
|
||||
}
|
||||
else if (dist)
|
||||
{
|
||||
fac = 1.0 + fabs(fixstep);
|
||||
}
|
||||
|
||||
if (fac != 0.0)
|
||||
{
|
||||
if (maxx * fac >= IXMAX_VAL)
|
||||
{
|
||||
// restore best noise
|
||||
fac = sfacfix0 / sfacfix;
|
||||
for (i = start; i < end; i++)
|
||||
xr_pow[i] *= fac;
|
||||
maxx *= fac;
|
||||
sfacfix *= fac;
|
||||
coderInfo->scale_factor[sb] = log(sfacfix) * log_ifqstep - 0.5;
|
||||
QuantizeBand(xr_pow, xi, IPOW20(coderInfo->global_gain), start, end,
|
||||
adj43);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (coderInfo->scale_factor[sb] < -10)
|
||||
{
|
||||
for (i = start; i < end; i++)
|
||||
xr_pow[i] *= fac;
|
||||
maxx *= fac;
|
||||
sfacfix *= fac;
|
||||
coderInfo->scale_factor[sb] = log(sfacfix) * log_ifqstep - 0.5;
|
||||
QuantizeBand(xr_pow, xi, IPOW20(coderInfo->global_gain), start, end,
|
||||
adj43);
|
||||
goto calcdist;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SortForGrouping(CoderInfo* coderInfo,
|
||||
PsyInfo *psyInfo,
|
||||
ChannelInfo *channelInfo,
|
||||
int *sfb_width_table,
|
||||
double *xr)
|
||||
{
|
||||
int i,j,ii;
|
||||
int index = 0;
|
||||
double xr_tmp[FRAME_LEN];
|
||||
int group_offset=0;
|
||||
int k=0;
|
||||
int windowOffset = 0;
|
||||
|
||||
|
||||
/* set up local variables for used quantInfo elements */
|
||||
int* sfb_offset = coderInfo->sfb_offset;
|
||||
int* nr_of_sfb = &(coderInfo->nr_of_sfb);
|
||||
int* window_group_length;
|
||||
int num_window_groups;
|
||||
*nr_of_sfb = coderInfo->max_sfb; /* Init to max_sfb */
|
||||
window_group_length = coderInfo->window_group_length;
|
||||
num_window_groups = coderInfo->num_window_groups;
|
||||
|
||||
/* calc org sfb_offset just for shortblock */
|
||||
sfb_offset[k]=0;
|
||||
for (k=1 ; k <*nr_of_sfb+1; k++) {
|
||||
sfb_offset[k] = sfb_offset[k-1] + sfb_width_table[k-1];
|
||||
}
|
||||
|
||||
/* sort the input spectral coefficients */
|
||||
index = 0;
|
||||
group_offset=0;
|
||||
for (i=0; i< num_window_groups; i++) {
|
||||
for (k=0; k<*nr_of_sfb; k++) {
|
||||
for (j=0; j < window_group_length[i]; j++) {
|
||||
for (ii=0;ii< sfb_width_table[k];ii++)
|
||||
xr_tmp[index++] = xr[ii+ sfb_offset[k] + BLOCK_LEN_SHORT*j +group_offset];
|
||||
}
|
||||
}
|
||||
group_offset += BLOCK_LEN_SHORT*window_group_length[i];
|
||||
}
|
||||
|
||||
for (k=0; k<FRAME_LEN; k++){
|
||||
xr[k] = xr_tmp[k];
|
||||
}
|
||||
|
||||
|
||||
/* now calc the new sfb_offset table for the whole p_spectrum vector*/
|
||||
index = 0;
|
||||
sfb_offset[index++] = 0;
|
||||
windowOffset = 0;
|
||||
for (i=0; i < num_window_groups; i++) {
|
||||
for (k=0 ; k <*nr_of_sfb; k++) {
|
||||
sfb_offset[index] = sfb_offset[index-1] + sfb_width_table[k]*window_group_length[i] ;
|
||||
index++;
|
||||
}
|
||||
windowOffset += window_group_length[i];
|
||||
}
|
||||
|
||||
*nr_of_sfb = *nr_of_sfb * num_window_groups; /* Number interleaved bands. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CalcAvgEnrg(CoderInfo *coderInfo,
|
||||
const double *xr)
|
||||
{
|
||||
int end, l;
|
||||
int last = 0;
|
||||
double totenrg = 0.0;
|
||||
|
||||
end = coderInfo->sfb_offset[coderInfo->nr_of_sfb];
|
||||
for (l = 0; l < end; l++)
|
||||
{
|
||||
if (xr[l])
|
||||
{
|
||||
last = l;
|
||||
totenrg += xr[l] * xr[l];
|
||||
}
|
||||
}
|
||||
last++;
|
||||
|
||||
coderInfo->lastx = last;
|
||||
coderInfo->avgenrg = totenrg / last;
|
||||
}
|
74
external/libfaac/libfaac/aacquant.h
vendored
Normal file
74
external/libfaac/libfaac/aacquant.h
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: aacquant.h,v 1.9 2003/10/12 16:43:39 knik Exp $
|
||||
*/
|
||||
|
||||
#ifndef AACQUANT_H
|
||||
#define AACQUANT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "coder.h"
|
||||
#include "psych.h"
|
||||
|
||||
#define IXMAX_VAL 8191
|
||||
#define PRECALC_SIZE (IXMAX_VAL+2)
|
||||
#define LARGE_BITS 100000
|
||||
#define SF_OFFSET 100
|
||||
|
||||
#define POW20(x) pow(2.0,((double)x)*.25)
|
||||
#define IPOW20(x) pow(2.0,-((double)x)*.1875)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
double *pow43;
|
||||
double *adj43;
|
||||
double quality;
|
||||
} AACQuantCfg;
|
||||
#pragma pack(pop)
|
||||
|
||||
void AACQuantizeInit(CoderInfo *coderInfo, unsigned int numChannels,
|
||||
AACQuantCfg *aacquantCfg);
|
||||
void AACQuantizeEnd(CoderInfo *coderInfo, unsigned int numChannels,
|
||||
AACQuantCfg *aacquantCfg);
|
||||
|
||||
int AACQuantize(CoderInfo *coderInfo,
|
||||
PsyInfo *psyInfo,
|
||||
ChannelInfo *channelInfo,
|
||||
int *cb_width,
|
||||
int num_cb,
|
||||
double *xr,
|
||||
AACQuantCfg *aacquantcfg);
|
||||
|
||||
int SortForGrouping(CoderInfo* coderInfo,
|
||||
PsyInfo *psyInfo,
|
||||
ChannelInfo *channelInfo,
|
||||
int *sfb_width_table,
|
||||
double *xr);
|
||||
void CalcAvgEnrg(CoderInfo *coderInfo,
|
||||
const double *xr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* AACQUANT_H */
|
381
external/libfaac/libfaac/backpred.c
vendored
Normal file
381
external/libfaac/libfaac/backpred.c
vendored
Normal file
|
@ -0,0 +1,381 @@
|
|||
/**********************************************************************
|
||||
|
||||
This software module was originally developed by
|
||||
and edited by Nokia in the course of
|
||||
development of the MPEG-2 NBC/MPEG-4 Audio standard
|
||||
ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an
|
||||
implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools
|
||||
as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives
|
||||
users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this
|
||||
software module or modifications thereof for use in hardware or
|
||||
software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio
|
||||
standards. Those intending to use this software module in hardware or
|
||||
software products are advised that this use may infringe existing
|
||||
patents. The original developer of this software module and his/her
|
||||
company, the subsequent editors and their companies, and ISO/IEC have
|
||||
no liability for use of this software module or modifications thereof
|
||||
in an implementation. Copyright is not released for non MPEG-2
|
||||
NBC/MPEG-4 Audio conforming products. The original developer retains
|
||||
full right to use the code for his/her own purpose, assign or donate
|
||||
the code to a third party and to inhibit third party from using the
|
||||
code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This
|
||||
copyright notice must be included in all copies or derivative works.
|
||||
|
||||
Copyright (c) 1997.
|
||||
**********************************************************************/
|
||||
/*
|
||||
* $Id: backpred.c,v 1.5 2001/09/04 18:39:35 menno Exp $
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "frame.h"
|
||||
#include "coder.h"
|
||||
#include "channels.h"
|
||||
#include "backpred.h"
|
||||
|
||||
|
||||
void PredInit(faacEncHandle hEncoder)
|
||||
{
|
||||
unsigned int channel;
|
||||
|
||||
for (channel = 0; channel < hEncoder->numChannels; channel++) {
|
||||
BwpInfo *bwpInfo = &(hEncoder->coderInfo[channel].bwpInfo);
|
||||
|
||||
bwpInfo->psy_init_mc = 0;
|
||||
bwpInfo->reset_count_mc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void PredCalcPrediction(double *act_spec, double *last_spec, int btype,
|
||||
int nsfb,
|
||||
int *isfb_width,
|
||||
CoderInfo *coderInfo,
|
||||
ChannelInfo *channelInfo,
|
||||
int chanNum)
|
||||
{
|
||||
int i, k, j, cb_long;
|
||||
int leftChanNum;
|
||||
int isRightWithCommonWindow;
|
||||
double num_bit, snr[SBMAX_L];
|
||||
double energy[BLOCK_LEN_LONG], snr_p[BLOCK_LEN_LONG], temp1, temp2;
|
||||
ChannelInfo *thisChannel;
|
||||
|
||||
/* Set pointers for specified channel number */
|
||||
/* int psy_init; */
|
||||
int *psy_init;
|
||||
double (*dr)[BLOCK_LEN_LONG],(*e)[BLOCK_LEN_LONG];
|
||||
double (*K)[BLOCK_LEN_LONG], (*R)[BLOCK_LEN_LONG];
|
||||
double (*VAR)[BLOCK_LEN_LONG], (*KOR)[BLOCK_LEN_LONG];
|
||||
double *sb_samples_pred;
|
||||
int *thisLineNeedsResetting;
|
||||
/* int reset_count; */
|
||||
int *reset_count;
|
||||
int *pred_global_flag;
|
||||
int *pred_sfb_flag;
|
||||
int *reset_group;
|
||||
|
||||
/* Set pointers for this chanNum */
|
||||
pred_global_flag = &(coderInfo[chanNum].pred_global_flag);
|
||||
pred_sfb_flag = coderInfo[chanNum].pred_sfb_flag;
|
||||
reset_group = &(coderInfo[chanNum].reset_group_number);
|
||||
psy_init = &coderInfo[chanNum].bwpInfo.psy_init_mc;
|
||||
dr = &coderInfo[chanNum].bwpInfo.dr_mc[0];
|
||||
e = &coderInfo[chanNum].bwpInfo.e_mc[0];
|
||||
K = &coderInfo[chanNum].bwpInfo.K_mc[0];
|
||||
R = &coderInfo[chanNum].bwpInfo.R_mc[0];
|
||||
VAR = &coderInfo[chanNum].bwpInfo.VAR_mc[0];
|
||||
KOR = &coderInfo[chanNum].bwpInfo.KOR_mc[0];
|
||||
sb_samples_pred = &coderInfo[chanNum].bwpInfo.sb_samples_pred_mc[0];
|
||||
thisLineNeedsResetting = &coderInfo[chanNum].bwpInfo.thisLineNeedsResetting_mc[0];
|
||||
reset_count = &coderInfo[chanNum].bwpInfo.reset_count_mc;
|
||||
|
||||
thisChannel = &(channelInfo[chanNum]);
|
||||
*psy_init = (*psy_init && (btype!=2));
|
||||
|
||||
if((*psy_init) == 0) {
|
||||
for (j=0; j<BLOCK_LEN_LONG; j++) {
|
||||
thisLineNeedsResetting[j]=1;
|
||||
}
|
||||
*psy_init = 1;
|
||||
}
|
||||
|
||||
if (btype==2) {
|
||||
pred_global_flag[0]=0;
|
||||
/* SHORT WINDOWS reset all the co-efficients */
|
||||
if (thisChannel->ch_is_left) {
|
||||
(*reset_count)++;
|
||||
if (*reset_count >= 31 * RESET_FRAME)
|
||||
*reset_count = RESET_FRAME;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************/
|
||||
/* Compute state using last_spec */
|
||||
/**************************************************/
|
||||
for (i=0;i<BLOCK_LEN_LONG;i++)
|
||||
{
|
||||
/* e[0][i]=last_spec[i]; */
|
||||
e[0][i]=last_spec[i]+sb_samples_pred[i];
|
||||
|
||||
for(j=1;j<=LPC;j++)
|
||||
e[j][i] = e[j-1][i]-K[j][i]*R[j-1][i];
|
||||
|
||||
for(j=1;j<LPC;j++)
|
||||
dr[j][i] = K[j][i]*e[j-1][i];
|
||||
|
||||
for(j=1;j<=LPC;j++) {
|
||||
VAR[j][i] = ALPHA*VAR[j][i]+.5*(R[j-1][i]*R[j-1][i]+e[j-1][i]*e[j-1][i]);
|
||||
KOR[j][i] = ALPHA*KOR[j][i]+R[j-1][i]*e[j-1][i];
|
||||
}
|
||||
|
||||
for(j=LPC-1;j>=1;j--)
|
||||
R[j][i] = A*(R[j-1][i]-dr[j][i]);
|
||||
R[0][i] = A*e[0][i];
|
||||
}
|
||||
|
||||
|
||||
/**************************************************/
|
||||
/* Reset state here if resets were sent */
|
||||
/**************************************************/
|
||||
for (i=0;i<BLOCK_LEN_LONG;i++) {
|
||||
if (thisLineNeedsResetting[i]) {
|
||||
for (j = 0; j <= LPC; j++)
|
||||
{
|
||||
K[j][i] = 0.0;
|
||||
e[j][i] = 0.0;
|
||||
R[j][i] = 0.0;
|
||||
VAR[j][i] = 1.0;
|
||||
KOR[j][i] = 0.0;
|
||||
dr[j][i] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**************************************************/
|
||||
/* Compute predictor coefficients, predicted data */
|
||||
/**************************************************/
|
||||
for (i=0;i<BLOCK_LEN_LONG;i++)
|
||||
{
|
||||
for(j=1;j<=LPC;j++) {
|
||||
if(VAR[j][i]>MINVAR)
|
||||
K[j][i] = KOR[j][i]/VAR[j][i]*B;
|
||||
else
|
||||
K[j][i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (k=0; k<BLOCK_LEN_LONG; k++)
|
||||
{
|
||||
sb_samples_pred[k]=0.0;
|
||||
for (i=1; i<=LPC; i++)
|
||||
sb_samples_pred[k]+=K[i][k]*R[i-1][k];
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************/
|
||||
/* If this is the right channel of a channel_pair_element, */
|
||||
/* AND common_window is 1 in this channel_pair_element, */
|
||||
/* THEN copy predictor data to use from the left channel. */
|
||||
/* ELSE determine independent predictor data and resets. */
|
||||
/***********************************************************/
|
||||
/* BE CAREFUL HERE, this assumes that predictor data has */
|
||||
/* already been determined for the left channel!! */
|
||||
/***********************************************************/
|
||||
isRightWithCommonWindow = 0; /* Is this a right channel with common_window?*/
|
||||
if ((thisChannel->cpe)&&( !(thisChannel->ch_is_left))) {
|
||||
leftChanNum = thisChannel->paired_ch;
|
||||
if (channelInfo[leftChanNum].common_window) {
|
||||
isRightWithCommonWindow = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (isRightWithCommonWindow) {
|
||||
|
||||
/**************************************************/
|
||||
/* Use predictor data from the left channel. */
|
||||
/**************************************************/
|
||||
CopyPredInfo(&(coderInfo[chanNum]),&(coderInfo[leftChanNum]));
|
||||
|
||||
/* Make sure to turn off bands with intensity stereo */
|
||||
#if 0
|
||||
if (thisChannel->is_info.is_present) {
|
||||
for (i=0; i<nsfb; i++) {
|
||||
if (thisChannel->is_info.is_used[i]) {
|
||||
pred_sfb_flag[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
cb_long=0;
|
||||
for (i=0; i<nsfb; i++)
|
||||
{
|
||||
if (!pred_sfb_flag[i]) {
|
||||
for (j=cb_long; j<cb_long+isfb_width[i]; j++)
|
||||
sb_samples_pred[j]=0.0;
|
||||
}
|
||||
cb_long+=isfb_width[i];
|
||||
}
|
||||
|
||||
/* Disable prediction for bands nsfb through SBMAX_L */
|
||||
for (i=j;i<BLOCK_LEN_LONG;i++) {
|
||||
sb_samples_pred[i]=0.0;
|
||||
}
|
||||
for (i=nsfb;i<SBMAX_L;i++) {
|
||||
pred_sfb_flag[i]=0;
|
||||
}
|
||||
|
||||
/* Is global enable set, if not enabled predicted samples are zeroed */
|
||||
if(!pred_global_flag[0]) {
|
||||
for (j=0; j<BLOCK_LEN_LONG; j++)
|
||||
sb_samples_pred[j]=0.0;
|
||||
}
|
||||
for (j=0; j<BLOCK_LEN_LONG; j++)
|
||||
act_spec[j]-=sb_samples_pred[j];
|
||||
|
||||
} else {
|
||||
|
||||
/**************************************************/
|
||||
/* Determine whether to enable/disable prediction */
|
||||
/**************************************************/
|
||||
|
||||
for (k=0; k<BLOCK_LEN_LONG; k++) {
|
||||
energy[k]=act_spec[k]*act_spec[k];
|
||||
snr_p[k]=(act_spec[k]-sb_samples_pred[k])*(act_spec[k]-sb_samples_pred[k]);
|
||||
}
|
||||
|
||||
cb_long=0;
|
||||
for (i=0; i<nsfb; i++) {
|
||||
pred_sfb_flag[i]=1;
|
||||
temp1=0.0;
|
||||
temp2=0.0;
|
||||
for (j=cb_long; j<cb_long+isfb_width[i]; j++) {
|
||||
temp1+=energy[j];
|
||||
temp2+=snr_p[j];
|
||||
}
|
||||
if(temp2<1.e-20)
|
||||
temp2=1.e-20;
|
||||
if(temp1!=0.0)
|
||||
snr[i]=-10.*log10((double ) temp2/temp1);
|
||||
else
|
||||
snr[i]=0.0;
|
||||
|
||||
if(snr[i]<=0.0) {
|
||||
pred_sfb_flag[i]=0;
|
||||
for (j=cb_long; j<cb_long+isfb_width[i]; j++)
|
||||
sb_samples_pred[j]=0.0;
|
||||
}
|
||||
cb_long+=isfb_width[i];
|
||||
}
|
||||
|
||||
/* Disable prediction for bands nsfb through SBMAX_L */
|
||||
for (i=j;i<BLOCK_LEN_LONG;i++) {
|
||||
sb_samples_pred[i]=0.0;
|
||||
}
|
||||
for (i=nsfb;i<SBMAX_L;i++) {
|
||||
pred_sfb_flag[i]=0;
|
||||
}
|
||||
|
||||
num_bit=0.0;
|
||||
for (i=0; i<nsfb; i++)
|
||||
if(snr[i]>0.0)
|
||||
num_bit+=snr[i]/6.*isfb_width[i];
|
||||
|
||||
/* Determine global enable, if not enabled predicted samples are zeroed */
|
||||
pred_global_flag[0]=1;
|
||||
if(num_bit<50) {
|
||||
pred_global_flag[0]=0; num_bit=0.0;
|
||||
for (j=0; j<BLOCK_LEN_LONG; j++)
|
||||
sb_samples_pred[j]=0.0;
|
||||
}
|
||||
for (j=0; j<BLOCK_LEN_LONG; j++)
|
||||
act_spec[j]-=sb_samples_pred[j];
|
||||
|
||||
}
|
||||
|
||||
/**********************************************************/
|
||||
/* If this is a left channel, determine pred resets. */
|
||||
/* If this is a right channel, using pred reset data from */
|
||||
/* left channel. Keep left and right resets in sync. */
|
||||
/**********************************************************/
|
||||
if ((thisChannel->cpe)&&( !(thisChannel->ch_is_left))) {
|
||||
/* if (!thisChannel->ch_is_left) {*/
|
||||
/**********************************************************/
|
||||
/* Using predictor reset data from the left channel. */
|
||||
/**********************************************************/
|
||||
reset_count = &coderInfo[leftChanNum].bwpInfo.reset_count_mc;
|
||||
/* Reset the frame counter */
|
||||
for (i=0;i<BLOCK_LEN_LONG;i++) {
|
||||
thisLineNeedsResetting[i]=0;
|
||||
}
|
||||
reset_group = &(coderInfo[chanNum].reset_group_number);
|
||||
if (*reset_count % RESET_FRAME == 0)
|
||||
{ /* Send a reset in this frame */
|
||||
*reset_group = *reset_count / 8;
|
||||
for (i = *reset_group - 1; i < BLOCK_LEN_LONG; i += 30)
|
||||
{
|
||||
thisLineNeedsResetting[i]=1;
|
||||
}
|
||||
}
|
||||
else
|
||||
*reset_group = -1;
|
||||
} else {
|
||||
/******************************************************************/
|
||||
/* Determine whether a prediction reset is required - if so, then */
|
||||
/* set reset flag for the appropriate group. */
|
||||
/******************************************************************/
|
||||
|
||||
/* Increase counter on left channel, keep left and right resets in sync */
|
||||
(*reset_count)++;
|
||||
|
||||
/* Reset the frame counter */
|
||||
for (i=0;i<BLOCK_LEN_LONG;i++) {
|
||||
thisLineNeedsResetting[i]=0;
|
||||
}
|
||||
if (*reset_count >= 31 * RESET_FRAME)
|
||||
*reset_count = RESET_FRAME;
|
||||
if (*reset_count % RESET_FRAME == 0)
|
||||
{ /* Send a reset in this frame */
|
||||
*reset_group = *reset_count / 8;
|
||||
for (i = *reset_group - 1; i < BLOCK_LEN_LONG; i += 30)
|
||||
{
|
||||
thisLineNeedsResetting[i]=1;
|
||||
}
|
||||
}
|
||||
else
|
||||
*reset_group = -1;
|
||||
}
|
||||
|
||||
|
||||
/* Ensure that prediction data is sent when there is a prediction
|
||||
* reset.
|
||||
*/
|
||||
if (*reset_group != -1 && pred_global_flag[0] == 0)
|
||||
{
|
||||
pred_global_flag[0] = 1;
|
||||
for (i = 0; i < nsfb; i++)
|
||||
pred_sfb_flag[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CopyPredInfo(CoderInfo *right, CoderInfo *left)
|
||||
{
|
||||
int band;
|
||||
|
||||
right->pred_global_flag = left->pred_global_flag;
|
||||
right->reset_group_number = left->reset_group_number;
|
||||
|
||||
for (band = 0; band<MAX_SCFAC_BANDS; band++) {
|
||||
right->pred_sfb_flag[band] = left->pred_sfb_flag[band];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
51
external/libfaac/libfaac/backpred.h
vendored
Normal file
51
external/libfaac/libfaac/backpred.h
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: backpred.h,v 1.5 2001/06/08 18:01:09 menno Exp $
|
||||
*/
|
||||
|
||||
#ifndef _AAC_BACK_H_INCLUDED
|
||||
#define _AAC_BACK_H_INCLUDED
|
||||
|
||||
#define PRED_ALPHA 0.90625
|
||||
#define PRED_A 0.953125
|
||||
#define PRED_B 0.953125
|
||||
|
||||
#define ALPHA PRED_ALPHA
|
||||
#define A PRED_A
|
||||
#define B PRED_B
|
||||
#define MINVAR 1.e-10
|
||||
|
||||
/* Reset every RESET_FRAME frames. */
|
||||
#define RESET_FRAME 8
|
||||
|
||||
void PredCalcPrediction(double *act_spec,
|
||||
double *last_spec,
|
||||
int btype,
|
||||
int nsfb,
|
||||
int *isfb_width,
|
||||
CoderInfo *coderInfo,
|
||||
ChannelInfo *channelInfo,
|
||||
int chanNum);
|
||||
|
||||
void PredInit(faacEncHandle hEncoder);
|
||||
|
||||
void CopyPredInfo(CoderInfo *right, CoderInfo *left);
|
||||
|
||||
|
||||
#endif
|
1496
external/libfaac/libfaac/bitstream.c
vendored
Normal file
1496
external/libfaac/libfaac/bitstream.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
172
external/libfaac/libfaac/bitstream.h
vendored
Normal file
172
external/libfaac/libfaac/bitstream.h
vendored
Normal file
|
@ -0,0 +1,172 @@
|
|||
/**********************************************************************
|
||||
MPEG-4 Audio VM
|
||||
Bit stream module
|
||||
|
||||
|
||||
|
||||
This software module was originally developed by
|
||||
|
||||
Heiko Purnhagen (University of Hannover)
|
||||
|
||||
and edited by
|
||||
|
||||
in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard
|
||||
ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an
|
||||
implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools
|
||||
as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives
|
||||
users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this
|
||||
software module or modifications thereof for use in hardware or
|
||||
software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio
|
||||
standards. Those intending to use this software module in hardware or
|
||||
software products are advised that this use may infringe existing
|
||||
patents. The original developer of this software module and his/her
|
||||
company, the subsequent editors and their companies, and ISO/IEC have
|
||||
no liability for use of this software module or modifications thereof
|
||||
in an implementation. Copyright is not released for non MPEG-2
|
||||
NBC/MPEG-4 Audio conforming products. The original developer retains
|
||||
full right to use the code for his/her own purpose, assign or donate
|
||||
the code to a third party and to inhibit third party from using the
|
||||
code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This
|
||||
copyright notice must be included in all copies or derivative works.
|
||||
|
||||
Copyright (c) 1996.
|
||||
**********************************************************************/
|
||||
/*
|
||||
* $Id: bitstream.h,v 1.14 2004/07/04 12:10:52 corrados Exp $
|
||||
*/
|
||||
|
||||
#ifndef BITSTREAM_H
|
||||
#define BITSTREAM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "frame.h"
|
||||
#include "coder.h"
|
||||
#include "channels.h"
|
||||
|
||||
/*
|
||||
* Raw bitstream constants
|
||||
*/
|
||||
#define LEN_SE_ID 3
|
||||
#define LEN_TAG 4
|
||||
#define LEN_GLOB_GAIN 8
|
||||
#define LEN_COM_WIN 1
|
||||
#define LEN_ICS_RESERV 1
|
||||
#define LEN_WIN_SEQ 2
|
||||
#define LEN_WIN_SH 1
|
||||
#define LEN_MAX_SFBL 6
|
||||
#define LEN_MAX_SFBS 4
|
||||
#define LEN_CB 4
|
||||
#define LEN_SCL_PCM 8
|
||||
#define LEN_PRED_PRES 1
|
||||
#define LEN_PRED_RST 1
|
||||
#define LEN_PRED_RSTGRP 5
|
||||
#define LEN_PRED_ENAB 1
|
||||
#define LEN_MASK_PRES 2
|
||||
#define LEN_MASK 1
|
||||
#define LEN_PULSE_PRES 1
|
||||
|
||||
#define LEN_TNS_PRES 1
|
||||
#define LEN_TNS_NFILTL 2
|
||||
#define LEN_TNS_NFILTS 1
|
||||
#define LEN_TNS_COEFF_RES 1
|
||||
#define LEN_TNS_LENGTHL 6
|
||||
#define LEN_TNS_LENGTHS 4
|
||||
#define LEN_TNS_ORDERL 5
|
||||
#define LEN_TNS_ORDERS 3
|
||||
#define LEN_TNS_DIRECTION 1
|
||||
#define LEN_TNS_COMPRESS 1
|
||||
#define LEN_GAIN_PRES 1
|
||||
|
||||
#define LEN_NEC_NPULSE 2
|
||||
#define LEN_NEC_ST_SFB 6
|
||||
#define LEN_NEC_POFF 5
|
||||
#define LEN_NEC_PAMP 4
|
||||
#define NUM_NEC_LINES 4
|
||||
#define NEC_OFFSET_AMP 4
|
||||
|
||||
#define LEN_NCC 3
|
||||
#define LEN_IS_CPE 1
|
||||
#define LEN_CC_LR 1
|
||||
#define LEN_CC_DOM 1
|
||||
#define LEN_CC_SGN 1
|
||||
#define LEN_CCH_GES 2
|
||||
#define LEN_CCH_CGP 1
|
||||
#define LEN_D_CNT 4
|
||||
#define LEN_D_ESC 12
|
||||
#define LEN_F_CNT 4
|
||||
#define LEN_F_ESC 8
|
||||
#define LEN_BYTE 8
|
||||
#define LEN_PAD_DATA 8
|
||||
|
||||
#define LEN_PC_COMM 8
|
||||
|
||||
#ifdef DRM
|
||||
# define LEN_HCR_REORDSD 14
|
||||
# define LEN_HCR_LONGCW 6
|
||||
# define FIRST_PAIR_HCB 5
|
||||
# define QUAD_LEN 4
|
||||
# define PAIR_LEN 2
|
||||
# define ESC_HCB 11
|
||||
#endif
|
||||
|
||||
#define ID_SCE 0
|
||||
#define ID_CPE 1
|
||||
#define ID_CCE 2
|
||||
#define ID_LFE 3
|
||||
#define ID_DSE 4
|
||||
#define ID_PCE 5
|
||||
#define ID_FIL 6
|
||||
#define ID_END 7
|
||||
|
||||
|
||||
/* MPEG ID's */
|
||||
#define MPEG2 1
|
||||
#define MPEG4 0
|
||||
|
||||
/* AAC object types */
|
||||
#define MAIN 1
|
||||
#define LOW 2
|
||||
#define SSR 3
|
||||
#define LTP 4
|
||||
|
||||
|
||||
#define BYTE_NUMBIT 8 /* bits in byte (char) */
|
||||
#define LONG_NUMBIT 32 /* bits in unsigned long */
|
||||
#define bit2byte(a) (((a)+BYTE_NUMBIT-1)/BYTE_NUMBIT)
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char *data; /* data bits */
|
||||
long numBit; /* number of bits in buffer */
|
||||
long size; /* buffer size in bytes */
|
||||
long currentBit; /* current bit position in bit stream */
|
||||
long numByte; /* number of bytes read/written (only file) */
|
||||
} BitStream;
|
||||
|
||||
|
||||
|
||||
int WriteBitstream(faacEncHandle hEncoder,
|
||||
CoderInfo *coderInfo,
|
||||
ChannelInfo *channelInfo,
|
||||
BitStream *bitStream,
|
||||
int numChannels);
|
||||
|
||||
|
||||
BitStream *OpenBitStream(int size, unsigned char *buffer);
|
||||
|
||||
int CloseBitStream(BitStream *bitStream);
|
||||
|
||||
int PutBit(BitStream *bitStream,
|
||||
unsigned long data,
|
||||
int numBit);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* BITSTREAM_H */
|
||||
|
110
external/libfaac/libfaac/channels.c
vendored
Normal file
110
external/libfaac/libfaac/channels.c
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
/************************* MPEG-2 NBC Audio Decoder **************************
|
||||
* *
|
||||
"This software module was originally developed in the course of
|
||||
development of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7,
|
||||
14496-1,2 and 3. This software module is an implementation of a part of one or more
|
||||
MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4
|
||||
Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio
|
||||
standards free license to this software module or modifications thereof for use in
|
||||
hardware or software products claiming conformance to the MPEG-2 NBC/MPEG-4
|
||||
Audio standards. Those intending to use this software module in hardware or
|
||||
software products are advised that this use may infringe existing patents.
|
||||
The original developer of this software module and his/her company, the subsequent
|
||||
editors and their companies, and ISO/IEC have no liability for use of this software
|
||||
module or modifications thereof in an implementation. Copyright is not released for
|
||||
non MPEG-2 NBC/MPEG-4 Audio conforming products.The original developer
|
||||
retains full right to use the code for his/her own purpose, assign or donate the
|
||||
code to a third party and to inhibit third party from using the code for non
|
||||
MPEG-2 NBC/MPEG-4 Audio conforming products. This copyright notice must
|
||||
be included in all copies or derivative works."
|
||||
Copyright(c)1996.
|
||||
* *
|
||||
****************************************************************************/
|
||||
/*
|
||||
* $Id: channels.c,v 1.5 2001/09/04 18:39:35 menno Exp $
|
||||
*/
|
||||
|
||||
#include "channels.h"
|
||||
#include "coder.h"
|
||||
#include "util.h"
|
||||
|
||||
/* If LFE present */
|
||||
/* Num channels # of SCE's # of CPE's #of LFE's */
|
||||
/* ============ ========== ========== ========= */
|
||||
/* 1 1 0 0 */
|
||||
/* 2 0 1 0 */
|
||||
/* 3 1 1 0 */
|
||||
/* 4 1 1 1 */
|
||||
/* 5 1 2 0 */
|
||||
/* For more than 5 channels, use the following elements: */
|
||||
/* 2*N 1 2*(N-1) 1 */
|
||||
/* 2*N+1 1 2*N 0 */
|
||||
/* */
|
||||
/* Else: */
|
||||
/* */
|
||||
/* Num channels # of SCE's # of CPE's #of LFE's */
|
||||
/* ============ ========== ========== ========= */
|
||||
/* 1 1 0 0 */
|
||||
/* 2 0 1 0 */
|
||||
/* 3 1 1 0 */
|
||||
/* 4 2 1 0 */
|
||||
/* 5 1 2 0 */
|
||||
/* For more than 5 channels, use the following elements: */
|
||||
/* 2*N 2 2*(N-1) 0 */
|
||||
/* 2*N+1 1 2*N 0 */
|
||||
|
||||
void GetChannelInfo(ChannelInfo *channelInfo, int numChannels, int useLfe)
|
||||
{
|
||||
int sceTag = 0;
|
||||
int lfeTag = 0;
|
||||
int cpeTag = 0;
|
||||
int numChannelsLeft = numChannels;
|
||||
|
||||
|
||||
/* First element is sce, except for 2 channel case */
|
||||
if (numChannelsLeft != 2) {
|
||||
channelInfo[numChannels-numChannelsLeft].present = 1;
|
||||
channelInfo[numChannels-numChannelsLeft].tag = sceTag++;
|
||||
channelInfo[numChannels-numChannelsLeft].cpe = 0;
|
||||
channelInfo[numChannels-numChannelsLeft].lfe = 0;
|
||||
numChannelsLeft--;
|
||||
}
|
||||
|
||||
/* Next elements are cpe's */
|
||||
while (numChannelsLeft > 1) {
|
||||
/* Left channel info */
|
||||
channelInfo[numChannels-numChannelsLeft].present = 1;
|
||||
channelInfo[numChannels-numChannelsLeft].tag = cpeTag++;
|
||||
channelInfo[numChannels-numChannelsLeft].cpe = 1;
|
||||
channelInfo[numChannels-numChannelsLeft].common_window = 0;
|
||||
channelInfo[numChannels-numChannelsLeft].ch_is_left = 1;
|
||||
channelInfo[numChannels-numChannelsLeft].paired_ch = numChannels-numChannelsLeft+1;
|
||||
channelInfo[numChannels-numChannelsLeft].lfe = 0;
|
||||
numChannelsLeft--;
|
||||
|
||||
/* Right channel info */
|
||||
channelInfo[numChannels-numChannelsLeft].present = 1;
|
||||
channelInfo[numChannels-numChannelsLeft].cpe = 1;
|
||||
channelInfo[numChannels-numChannelsLeft].common_window = 0;
|
||||
channelInfo[numChannels-numChannelsLeft].ch_is_left = 0;
|
||||
channelInfo[numChannels-numChannelsLeft].paired_ch = numChannels-numChannelsLeft-1;
|
||||
channelInfo[numChannels-numChannelsLeft].lfe = 0;
|
||||
numChannelsLeft--;
|
||||
}
|
||||
|
||||
/* Is there another channel left ? */
|
||||
if (numChannelsLeft) {
|
||||
if (useLfe) {
|
||||
channelInfo[numChannels-numChannelsLeft].present = 1;
|
||||
channelInfo[numChannels-numChannelsLeft].tag = lfeTag++;
|
||||
channelInfo[numChannels-numChannelsLeft].cpe = 0;
|
||||
channelInfo[numChannels-numChannelsLeft].lfe = 1;
|
||||
} else {
|
||||
channelInfo[numChannels-numChannelsLeft].present = 1;
|
||||
channelInfo[numChannels-numChannelsLeft].tag = sceTag++;
|
||||
channelInfo[numChannels-numChannelsLeft].cpe = 0;
|
||||
channelInfo[numChannels-numChannelsLeft].lfe = 0;
|
||||
}
|
||||
numChannelsLeft--;
|
||||
}
|
||||
}
|
54
external/libfaac/libfaac/channels.h
vendored
Normal file
54
external/libfaac/libfaac/channels.h
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: channels.h,v 1.7 2003/06/26 19:19:41 knik Exp $
|
||||
*/
|
||||
|
||||
#ifndef CHANNEL_H
|
||||
#define CHANNEL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "coder.h"
|
||||
|
||||
typedef struct {
|
||||
int is_present;
|
||||
int ms_used[MAX_SCFAC_BANDS];
|
||||
} MSInfo;
|
||||
|
||||
typedef struct {
|
||||
int tag;
|
||||
int present;
|
||||
int ch_is_left;
|
||||
int paired_ch;
|
||||
int common_window;
|
||||
int cpe;
|
||||
int sce;
|
||||
int lfe;
|
||||
MSInfo msInfo;
|
||||
} ChannelInfo;
|
||||
|
||||
void GetChannelInfo(ChannelInfo *channelInfo, int numChannels, int useLfe);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* CHANNEL_H */
|
210
external/libfaac/libfaac/coder.h
vendored
Normal file
210
external/libfaac/libfaac/coder.h
vendored
Normal file
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* Copyright (C) 2001 Menno Bakker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: coder.h,v 1.13 2005/02/02 07:49:10 sur Exp $
|
||||
*/
|
||||
|
||||
#ifndef CODER_H
|
||||
#define CODER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* Allow encoding of Digital Radio Mondiale (DRM) */
|
||||
//#define DRM
|
||||
|
||||
/* Allow encoding of Digital Radio Mondiale (DRM) with transform length 1024 */
|
||||
//#define DRM_1024
|
||||
|
||||
#define MAX_CHANNELS 64
|
||||
|
||||
#ifdef DRM
|
||||
#ifdef DRM_1024
|
||||
# define FRAME_LEN 1024
|
||||
# define BLOCK_LEN_LONG 1024
|
||||
# define BLOCK_LEN_SHORT 128
|
||||
#else
|
||||
# define FRAME_LEN 960
|
||||
# define BLOCK_LEN_LONG 960
|
||||
# define BLOCK_LEN_SHORT 120
|
||||
#endif /* DRM_1024 */
|
||||
#else
|
||||
# define FRAME_LEN 1024
|
||||
# define BLOCK_LEN_LONG 1024
|
||||
# define BLOCK_LEN_SHORT 128
|
||||
#endif
|
||||
|
||||
#define NSFB_LONG 51
|
||||
#define NSFB_SHORT 15
|
||||
#define MAX_SHORT_WINDOWS 8
|
||||
#define MAX_SCFAC_BANDS ((NSFB_SHORT+1)*MAX_SHORT_WINDOWS)
|
||||
|
||||
enum WINDOW_TYPE {
|
||||
ONLY_LONG_WINDOW,
|
||||
LONG_SHORT_WINDOW,
|
||||
ONLY_SHORT_WINDOW,
|
||||
SHORT_LONG_WINDOW
|
||||
};
|
||||
|
||||
#define TNS_MAX_ORDER 20
|
||||
#define DEF_TNS_GAIN_THRESH 1.4
|
||||
#define DEF_TNS_COEFF_THRESH 0.1
|
||||
#define DEF_TNS_COEFF_RES 4
|
||||
#define DEF_TNS_RES_OFFSET 3
|
||||
#define LEN_TNS_NFILTL 2
|
||||
#define LEN_TNS_NFILTS 1
|
||||
|
||||
#define DELAY 2048
|
||||
#define LEN_LTP_DATA_PRESENT 1
|
||||
#define LEN_LTP_LAG 11
|
||||
#define LEN_LTP_COEF 3
|
||||
#define LEN_LTP_SHORT_USED 1
|
||||
#define LEN_LTP_SHORT_LAG_PRESENT 1
|
||||
#define LEN_LTP_SHORT_LAG 5
|
||||
#define LTP_LAG_OFFSET 16
|
||||
#define LEN_LTP_LONG_USED 1
|
||||
#define MAX_LT_PRED_LONG_SFB 40
|
||||
#define MAX_LT_PRED_SHORT_SFB 13
|
||||
#define SHORT_SQ_OFFSET (BLOCK_LEN_LONG-(BLOCK_LEN_SHORT*4+BLOCK_LEN_SHORT/2))
|
||||
#define CODESIZE 8
|
||||
#define NOK_LT_BLEN (3 * BLOCK_LEN_LONG)
|
||||
|
||||
#define SBMAX_L 49
|
||||
#define LPC 2
|
||||
|
||||
typedef struct {
|
||||
int order; /* Filter order */
|
||||
int direction; /* Filtering direction */
|
||||
int coefCompress; /* Are coeffs compressed? */
|
||||
int length; /* Length, in bands */
|
||||
double aCoeffs[TNS_MAX_ORDER+1]; /* AR Coefficients */
|
||||
double kCoeffs[TNS_MAX_ORDER+1]; /* Reflection Coefficients */
|
||||
int index[TNS_MAX_ORDER+1]; /* Coefficient indices */
|
||||
} TnsFilterData;
|
||||
|
||||
typedef struct {
|
||||
int numFilters; /* Number of filters */
|
||||
int coefResolution; /* Coefficient resolution */
|
||||
TnsFilterData tnsFilter[1<<LEN_TNS_NFILTL]; /* TNS filters */
|
||||
} TnsWindowData;
|
||||
|
||||
typedef struct {
|
||||
int tnsDataPresent;
|
||||
int tnsMinBandNumberLong;
|
||||
int tnsMinBandNumberShort;
|
||||
int tnsMaxBandsLong;
|
||||
int tnsMaxBandsShort;
|
||||
int tnsMaxOrderLong;
|
||||
int tnsMaxOrderShort;
|
||||
TnsWindowData windowData[MAX_SHORT_WINDOWS]; /* TNS data per window */
|
||||
} TnsInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int weight_idx;
|
||||
double weight;
|
||||
int sbk_prediction_used[MAX_SHORT_WINDOWS];
|
||||
int sfb_prediction_used[MAX_SCFAC_BANDS];
|
||||
int delay[MAX_SHORT_WINDOWS];
|
||||
int global_pred_flag;
|
||||
int side_info;
|
||||
double *buffer;
|
||||
double *mdct_predicted;
|
||||
|
||||
double *time_buffer;
|
||||
double *ltp_overlap_buffer;
|
||||
} LtpInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int psy_init_mc;
|
||||
double dr_mc[LPC][BLOCK_LEN_LONG],e_mc[LPC+1+1][BLOCK_LEN_LONG];
|
||||
double K_mc[LPC+1][BLOCK_LEN_LONG], R_mc[LPC+1][BLOCK_LEN_LONG];
|
||||
double VAR_mc[LPC+1][BLOCK_LEN_LONG], KOR_mc[LPC+1][BLOCK_LEN_LONG];
|
||||
double sb_samples_pred_mc[BLOCK_LEN_LONG];
|
||||
int thisLineNeedsResetting_mc[BLOCK_LEN_LONG];
|
||||
int reset_count_mc;
|
||||
} BwpInfo;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int window_shape;
|
||||
int prev_window_shape;
|
||||
int block_type;
|
||||
int desired_block_type;
|
||||
|
||||
int global_gain;
|
||||
int scale_factor[MAX_SCFAC_BANDS];
|
||||
|
||||
int num_window_groups;
|
||||
int window_group_length[8];
|
||||
int max_sfb;
|
||||
int nr_of_sfb;
|
||||
int sfb_offset[250];
|
||||
int lastx;
|
||||
double avgenrg;
|
||||
|
||||
int spectral_count;
|
||||
|
||||
/* Huffman codebook selected for each sf band */
|
||||
int book_vector[MAX_SCFAC_BANDS];
|
||||
|
||||
/* Data of spectral bitstream elements, for each spectral pair,
|
||||
5 elements are required: 1*(esc)+2*(sign)+2*(esc value)=5 */
|
||||
int *data;
|
||||
|
||||
/* Lengths of spectral bitstream elements */
|
||||
int *len;
|
||||
|
||||
#ifdef DRM
|
||||
int *num_data_cw;
|
||||
int cur_cw;
|
||||
int all_sfb;
|
||||
|
||||
int iLenLongestCW;
|
||||
int iLenReordSpData;
|
||||
#endif
|
||||
|
||||
/* Holds the requantized spectrum */
|
||||
double *requantFreq;
|
||||
|
||||
TnsInfo tnsInfo;
|
||||
LtpInfo ltpInfo;
|
||||
BwpInfo bwpInfo;
|
||||
|
||||
int max_pred_sfb;
|
||||
int pred_global_flag;
|
||||
int pred_sfb_flag[MAX_SCFAC_BANDS];
|
||||
int reset_group_number;
|
||||
|
||||
} CoderInfo;
|
||||
|
||||
typedef struct {
|
||||
unsigned long sampling_rate; /* the following entries are for this sampling rate */
|
||||
int num_cb_long;
|
||||
int num_cb_short;
|
||||
int cb_width_long[NSFB_LONG];
|
||||
int cb_width_short[NSFB_SHORT];
|
||||
} SR_INFO;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* CODER_H */
|
704
external/libfaac/libfaac/fft.c
vendored
Normal file
704
external/libfaac/libfaac/fft.c
vendored
Normal file
|
@ -0,0 +1,704 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* $Id: fft.c,v 1.12 2005/02/02 07:49:55 sur Exp $
|
||||
* Copyright (C) 2002 Krzysztof Nikiel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "fft.h"
|
||||
#include "util.h"
|
||||
|
||||
#define MAXLOGM 9
|
||||
#define MAXLOGR 8
|
||||
|
||||
#if defined DRM && !defined DRM_1024
|
||||
|
||||
#include "kiss_fft/kiss_fft.h"
|
||||
#include "kiss_fft/kiss_fftr.h"
|
||||
|
||||
static const int logm_to_nfft[] =
|
||||
{
|
||||
/* 0 1 2 3 */
|
||||
0, 0, 0, 0,
|
||||
/* 4 5 6 7 */
|
||||
0, 0, 60, 0,
|
||||
/* 8 9 */
|
||||
240, 480
|
||||
};
|
||||
|
||||
void fft_initialize( FFT_Tables *fft_tables )
|
||||
{
|
||||
memset( fft_tables->cfg, 0, sizeof( fft_tables->cfg ) );
|
||||
}
|
||||
void fft_terminate( FFT_Tables *fft_tables )
|
||||
{
|
||||
unsigned int i;
|
||||
for ( i = 0; i < sizeof( fft_tables->cfg ) / sizeof( fft_tables->cfg[0] ); i++ )
|
||||
{
|
||||
if ( fft_tables->cfg[i][0] )
|
||||
{
|
||||
free( fft_tables->cfg[i][0] );
|
||||
fft_tables->cfg[i][0] = NULL;
|
||||
}
|
||||
if ( fft_tables->cfg[i][1] )
|
||||
{
|
||||
free( fft_tables->cfg[i][1] );
|
||||
fft_tables->cfg[i][1] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rfft( FFT_Tables *fft_tables, double *x, int logm )
|
||||
{
|
||||
#if 0
|
||||
/* sur: do not use real-only optimized FFT */
|
||||
double xi[1 << MAXLOGR];
|
||||
|
||||
int nfft;
|
||||
|
||||
if ( logm > MAXLOGR )
|
||||
{
|
||||
fprintf(stderr, "rfft size too big\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nfft = logm_to_nfft[logm];
|
||||
|
||||
if ( nfft )
|
||||
{
|
||||
//unsigned int i;
|
||||
//for ( i = 0; i < nfft; i++ )
|
||||
//{
|
||||
// xi[i] = 0.0;
|
||||
//}
|
||||
memset( xi, 0, nfft * sizeof( xi[0] ) );
|
||||
|
||||
fft( fft_tables, x, xi, logm );
|
||||
|
||||
memcpy( x + nfft / 2, xi, ( nfft / 2 ) * sizeof(x[0]) );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "bad config for logm = %d\n", logm);
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
#else
|
||||
/* sur: use real-only optimized FFT */
|
||||
|
||||
int nfft = 0;
|
||||
|
||||
kiss_fft_scalar fin[1 << MAXLOGR];
|
||||
kiss_fft_cpx fout[1 << MAXLOGR];
|
||||
|
||||
if ( logm > MAXLOGR )
|
||||
{
|
||||
fprintf(stderr, "fft size too big\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nfft = logm_to_nfft[logm];
|
||||
|
||||
if ( fft_tables->cfg[logm][0] == NULL )
|
||||
{
|
||||
if ( nfft )
|
||||
{
|
||||
fft_tables->cfg[logm][0] = kiss_fftr_alloc( nfft, 0, NULL, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "bad logm = %d\n", logm);
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( fft_tables->cfg[logm][0] )
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for ( i = 0; i < nfft; i++ )
|
||||
{
|
||||
fin[i] = x[i];
|
||||
}
|
||||
|
||||
kiss_fftr( (kiss_fftr_cfg)fft_tables->cfg[logm][0], fin, fout );
|
||||
|
||||
for ( i = 0; i < nfft / 2; i++ )
|
||||
{
|
||||
x[i] = fout[i].r;
|
||||
x[i + nfft / 2] = fout[i].i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "bad config for logm = %d\n", logm);
|
||||
exit( 1 );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void fft( FFT_Tables *fft_tables, double *xr, double *xi, int logm )
|
||||
{
|
||||
int nfft = 0;
|
||||
|
||||
kiss_fft_cpx fin[1 << MAXLOGM];
|
||||
kiss_fft_cpx fout[1 << MAXLOGM];
|
||||
|
||||
if ( logm > MAXLOGM )
|
||||
{
|
||||
fprintf(stderr, "fft size too big\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nfft = logm_to_nfft[logm];
|
||||
|
||||
if ( fft_tables->cfg[logm][0] == NULL )
|
||||
{
|
||||
if ( nfft )
|
||||
{
|
||||
fft_tables->cfg[logm][0] = kiss_fft_alloc( nfft, 0, NULL, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "bad logm = %d\n", logm);
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( fft_tables->cfg[logm][0] )
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for ( i = 0; i < nfft; i++ )
|
||||
{
|
||||
fin[i].r = xr[i];
|
||||
fin[i].i = xi[i];
|
||||
}
|
||||
|
||||
kiss_fft( (kiss_fft_cfg)fft_tables->cfg[logm][0], fin, fout );
|
||||
|
||||
for ( i = 0; i < nfft; i++ )
|
||||
{
|
||||
xr[i] = fout[i].r;
|
||||
xi[i] = fout[i].i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "bad config for logm = %d\n", logm);
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
void ffti( FFT_Tables *fft_tables, double *xr, double *xi, int logm )
|
||||
{
|
||||
int nfft = 0;
|
||||
|
||||
kiss_fft_cpx fin[1 << MAXLOGM];
|
||||
kiss_fft_cpx fout[1 << MAXLOGM];
|
||||
|
||||
if ( logm > MAXLOGM )
|
||||
{
|
||||
fprintf(stderr, "fft size too big\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nfft = logm_to_nfft[logm];
|
||||
|
||||
if ( fft_tables->cfg[logm][1] == NULL )
|
||||
{
|
||||
if ( nfft )
|
||||
{
|
||||
fft_tables->cfg[logm][1] = kiss_fft_alloc( nfft, 1, NULL, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "bad logm = %d\n", logm);
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( fft_tables->cfg[logm][1] )
|
||||
{
|
||||
unsigned int i;
|
||||
double fac = 1.0 / (double)nfft;
|
||||
|
||||
for ( i = 0; i < nfft; i++ )
|
||||
{
|
||||
fin[i].r = xr[i];
|
||||
fin[i].i = xi[i];
|
||||
}
|
||||
|
||||
kiss_fft( (kiss_fft_cfg)fft_tables->cfg[logm][1], fin, fout );
|
||||
|
||||
for ( i = 0; i < nfft; i++ )
|
||||
{
|
||||
xr[i] = fout[i].r * fac;
|
||||
xi[i] = fout[i].i * fac;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "bad config for logm = %d\n", logm);
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* sur: Trying to use cfft from libfaad2 -- it does not work 'from scratch' */
|
||||
//
|
||||
//#include "cfft/common.h"
|
||||
//
|
||||
//void fft_initialize( FFT_Tables *fft_tables )
|
||||
//{
|
||||
// memset( fft_tables->cfft, 0, sizeof( fft_tables->cfft ) );
|
||||
//}
|
||||
//void fft_terminate( FFT_Tables *fft_tables )
|
||||
//{
|
||||
// unsigned int i;
|
||||
// for ( i = 0; i < sizeof( fft_tables->cfft ) / sizeof( fft_tables->cfft[0] ); i++ )
|
||||
// {
|
||||
// if ( fft_tables->cfft[i] )
|
||||
// {
|
||||
// cfftu( fft_tables->cfft[i] );
|
||||
// fft_tables->cfft[i] = NULL;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void rfft( FFT_Tables *fft_tables, double *x, int logm )
|
||||
//{
|
||||
// double xi[1 << MAXLOGR];
|
||||
//
|
||||
// int nfft;
|
||||
//
|
||||
// if ( logm > MAXLOGR )
|
||||
// {
|
||||
// fprintf(stderr, "rfft size too big\n");
|
||||
// exit(1);
|
||||
// }
|
||||
//
|
||||
// nfft = logm_to_nfft[logm];
|
||||
//
|
||||
// if ( nfft )
|
||||
// {
|
||||
// unsigned int i;
|
||||
//
|
||||
// for ( i = 0; i < nfft; i++ )
|
||||
// {
|
||||
// xi[i] = 0.0;
|
||||
// }
|
||||
// //memset( xi, 0, nfft * sizeof( xi[0] ) );
|
||||
//
|
||||
// fft( fft_tables, x, xi, logm );
|
||||
//
|
||||
// memcpy( x + nfft / 2, xi, ( nfft / 2 ) * sizeof(x[0]) );
|
||||
//
|
||||
//#ifdef SUR_DEBUG_FFT
|
||||
// {
|
||||
// FILE* f = fopen( "fft.log", "at" );
|
||||
//
|
||||
// fprintf( f, "RFFT(%d)\n", nfft );
|
||||
//
|
||||
// for ( i = 0; i < nfft; i++ )
|
||||
// {
|
||||
// fprintf( f, ";%d;%g;%g\n", i, x[i], xi[i] );
|
||||
// }
|
||||
//
|
||||
// fclose( f );
|
||||
// }
|
||||
//#endif
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// fprintf( stderr, "bad config for logm = %d\n", logm);
|
||||
// exit( 1 );
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void fft( FFT_Tables *fft_tables, double *xr, double *xi, int logm )
|
||||
//{
|
||||
// int nfft;
|
||||
//
|
||||
// complex_t c[1 << MAXLOGM];
|
||||
//
|
||||
// if ( logm > MAXLOGM )
|
||||
// {
|
||||
// fprintf(stderr, "fft size too big\n");
|
||||
// exit(1);
|
||||
// }
|
||||
//
|
||||
// nfft = logm_to_nfft[logm];
|
||||
//
|
||||
// if ( fft_tables->cfft[logm] == NULL )
|
||||
// {
|
||||
// if ( nfft )
|
||||
// {
|
||||
// fft_tables->cfft[logm] = cffti( nfft );
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// fprintf(stderr, "bad logm = %d\n", logm);
|
||||
// exit( 1 );
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if ( fft_tables->cfft[logm] )
|
||||
// {
|
||||
// unsigned int i;
|
||||
//
|
||||
// for ( i = 0; i < nfft; i++ )
|
||||
// {
|
||||
// RE( c[i] ) = xr[i];
|
||||
// IM( c[i] ) = xi[i];
|
||||
// }
|
||||
//
|
||||
// cfftf( fft_tables->cfft[logm], c );
|
||||
//
|
||||
// for ( i = 0; i < nfft; i++ )
|
||||
// {
|
||||
// xr[i] = RE( c[i] );
|
||||
// xi[i] = IM( c[i] );
|
||||
// }
|
||||
//
|
||||
//#ifdef SUR_DEBUG_FFT
|
||||
// {
|
||||
// FILE* f = fopen( "fft.log", "at" );
|
||||
//
|
||||
// fprintf( f, "FFT(%d)\n", nfft );
|
||||
//
|
||||
// for ( i = 0; i < nfft; i++ )
|
||||
// {
|
||||
// fprintf( f, ";%d;%g;%g\n", i, xr[i], xi[i] );
|
||||
// }
|
||||
//
|
||||
// fclose( f );
|
||||
// }
|
||||
//#endif
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// fprintf( stderr, "bad config for logm = %d\n", logm);
|
||||
// exit( 1 );
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void ffti( FFT_Tables *fft_tables, double *xr, double *xi, int logm )
|
||||
//{
|
||||
// int nfft;
|
||||
//
|
||||
// complex_t c[1 << MAXLOGM];
|
||||
//
|
||||
// if ( logm > MAXLOGM )
|
||||
// {
|
||||
// fprintf(stderr, "fft size too big\n");
|
||||
// exit(1);
|
||||
// }
|
||||
//
|
||||
// nfft = logm_to_nfft[logm];
|
||||
//
|
||||
// if ( fft_tables->cfft[logm] == NULL )
|
||||
// {
|
||||
// if ( nfft )
|
||||
// {
|
||||
// fft_tables->cfft[logm] = cffti( nfft );
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// fprintf(stderr, "bad logm = %d\n", logm);
|
||||
// exit( 1 );
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if ( fft_tables->cfft[logm] )
|
||||
// {
|
||||
// unsigned int i;
|
||||
//
|
||||
// for ( i = 0; i < nfft; i++ )
|
||||
// {
|
||||
// RE( c[i] ) = xr[i];
|
||||
// IM( c[i] ) = xi[i];
|
||||
// }
|
||||
//
|
||||
// cfftb( fft_tables->cfft[logm], c );
|
||||
//
|
||||
// for ( i = 0; i < nfft; i++ )
|
||||
// {
|
||||
// xr[i] = RE( c[i] );
|
||||
// xi[i] = IM( c[i] );
|
||||
// }
|
||||
//
|
||||
//#ifdef SUR_DEBUG_FFT
|
||||
// {
|
||||
// FILE* f = fopen( "fft.log", "at" );
|
||||
//
|
||||
// fprintf( f, "FFTI(%d)\n", nfft );
|
||||
//
|
||||
// for ( i = 0; i < nfft; i++ )
|
||||
// {
|
||||
// fprintf( f, ";%d;%g;%g\n", i, xr[i], xi[i] );
|
||||
// }
|
||||
//
|
||||
// fclose( f );
|
||||
// }
|
||||
//#endif
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// fprintf( stderr, "bad config for logm = %d\n", logm);
|
||||
// exit( 1 );
|
||||
// }
|
||||
//}
|
||||
|
||||
#else /* !defined DRM || defined DRM_1024 */
|
||||
|
||||
void fft_initialize( FFT_Tables *fft_tables )
|
||||
{
|
||||
int i;
|
||||
fft_tables->costbl = AllocMemory( (MAXLOGM+1) * sizeof( fft_tables->costbl[0] ) );
|
||||
fft_tables->negsintbl = AllocMemory( (MAXLOGM+1) * sizeof( fft_tables->negsintbl[0] ) );
|
||||
fft_tables->reordertbl = AllocMemory( (MAXLOGM+1) * sizeof( fft_tables->reordertbl[0] ) );
|
||||
|
||||
for( i = 0; i< MAXLOGM+1; i++ )
|
||||
{
|
||||
fft_tables->costbl[i] = NULL;
|
||||
fft_tables->negsintbl[i] = NULL;
|
||||
fft_tables->reordertbl[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void fft_terminate( FFT_Tables *fft_tables )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i< MAXLOGM+1; i++ )
|
||||
{
|
||||
if( fft_tables->costbl[i] != NULL )
|
||||
FreeMemory( fft_tables->costbl[i] );
|
||||
|
||||
if( fft_tables->negsintbl[i] != NULL )
|
||||
FreeMemory( fft_tables->negsintbl[i] );
|
||||
|
||||
if( fft_tables->reordertbl[i] != NULL )
|
||||
FreeMemory( fft_tables->reordertbl[i] );
|
||||
}
|
||||
|
||||
FreeMemory( fft_tables->costbl );
|
||||
FreeMemory( fft_tables->negsintbl );
|
||||
FreeMemory( fft_tables->reordertbl );
|
||||
|
||||
fft_tables->costbl = NULL;
|
||||
fft_tables->negsintbl = NULL;
|
||||
fft_tables->reordertbl = NULL;
|
||||
}
|
||||
|
||||
static void reorder( FFT_Tables *fft_tables, double *x, int logm)
|
||||
{
|
||||
int i;
|
||||
int size = 1 << logm;
|
||||
unsigned short *r; //size
|
||||
|
||||
|
||||
if ( fft_tables->reordertbl[logm] == NULL ) // create bit reversing table
|
||||
{
|
||||
fft_tables->reordertbl[logm] = AllocMemory(size * sizeof(*(fft_tables->reordertbl[0])));
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
int reversed = 0;
|
||||
int b0;
|
||||
int tmp = i;
|
||||
|
||||
for (b0 = 0; b0 < logm; b0++)
|
||||
{
|
||||
reversed = (reversed << 1) | (tmp & 1);
|
||||
tmp >>= 1;
|
||||
}
|
||||
fft_tables->reordertbl[logm][i] = reversed;
|
||||
}
|
||||
}
|
||||
|
||||
r = fft_tables->reordertbl[logm];
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
int j = r[i];
|
||||
double tmp;
|
||||
|
||||
if (j <= i)
|
||||
continue;
|
||||
|
||||
tmp = x[i];
|
||||
x[i] = x[j];
|
||||
x[j] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
static void fft_proc(
|
||||
double *xr,
|
||||
double *xi,
|
||||
fftfloat *refac,
|
||||
fftfloat *imfac,
|
||||
int size)
|
||||
{
|
||||
int step, shift, pos;
|
||||
int exp, estep;
|
||||
|
||||
estep = size;
|
||||
for (step = 1; step < size; step *= 2)
|
||||
{
|
||||
int x1;
|
||||
int x2 = 0;
|
||||
estep >>= 1;
|
||||
for (pos = 0; pos < size; pos += (2 * step))
|
||||
{
|
||||
x1 = x2;
|
||||
x2 += step;
|
||||
exp = 0;
|
||||
for (shift = 0; shift < step; shift++)
|
||||
{
|
||||
double v2r, v2i;
|
||||
|
||||
v2r = xr[x2] * refac[exp] - xi[x2] * imfac[exp];
|
||||
v2i = xr[x2] * imfac[exp] + xi[x2] * refac[exp];
|
||||
|
||||
xr[x2] = xr[x1] - v2r;
|
||||
xr[x1] += v2r;
|
||||
|
||||
xi[x2] = xi[x1] - v2i;
|
||||
|
||||
xi[x1] += v2i;
|
||||
|
||||
exp += estep;
|
||||
|
||||
x1++;
|
||||
x2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void check_tables( FFT_Tables *fft_tables, int logm)
|
||||
{
|
||||
if( fft_tables->costbl[logm] == NULL )
|
||||
{
|
||||
int i;
|
||||
int size = 1 << logm;
|
||||
|
||||
if( fft_tables->negsintbl[logm] != NULL )
|
||||
FreeMemory( fft_tables->negsintbl[logm] );
|
||||
|
||||
fft_tables->costbl[logm] = AllocMemory((size / 2) * sizeof(*(fft_tables->costbl[0])));
|
||||
fft_tables->negsintbl[logm] = AllocMemory((size / 2) * sizeof(*(fft_tables->negsintbl[0])));
|
||||
|
||||
for (i = 0; i < (size >> 1); i++)
|
||||
{
|
||||
double theta = 2.0 * M_PI * ((double) i) / (double) size;
|
||||
fft_tables->costbl[logm][i] = cos(theta);
|
||||
fft_tables->negsintbl[logm][i] = -sin(theta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fft( FFT_Tables *fft_tables, double *xr, double *xi, int logm)
|
||||
{
|
||||
if (logm > MAXLOGM)
|
||||
{
|
||||
fprintf(stderr, "fft size too big\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (logm < 1)
|
||||
{
|
||||
//printf("logm < 1\n");
|
||||
return;
|
||||
}
|
||||
|
||||
check_tables( fft_tables, logm);
|
||||
|
||||
reorder( fft_tables, xr, logm);
|
||||
reorder( fft_tables, xi, logm);
|
||||
|
||||
fft_proc( xr, xi, fft_tables->costbl[logm], fft_tables->negsintbl[logm], 1 << logm );
|
||||
}
|
||||
|
||||
void rfft( FFT_Tables *fft_tables, double *x, int logm)
|
||||
{
|
||||
double xi[1 << MAXLOGR];
|
||||
|
||||
if (logm > MAXLOGR)
|
||||
{
|
||||
fprintf(stderr, "rfft size too big\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(xi, 0, (1 << logm) * sizeof(xi[0]));
|
||||
|
||||
fft( fft_tables, x, xi, logm);
|
||||
|
||||
memcpy(x + (1 << (logm - 1)), xi, (1 << (logm - 1)) * sizeof(*x));
|
||||
}
|
||||
|
||||
void ffti( FFT_Tables *fft_tables, double *xr, double *xi, int logm)
|
||||
{
|
||||
int i, size;
|
||||
double fac;
|
||||
double *xrp, *xip;
|
||||
|
||||
fft( fft_tables, xi, xr, logm);
|
||||
|
||||
size = 1 << logm;
|
||||
fac = 1.0 / size;
|
||||
xrp = xr;
|
||||
xip = xi;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
*xrp++ *= fac;
|
||||
*xip++ *= fac;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* defined DRM && !defined DRM_1024 */
|
||||
|
||||
/*
|
||||
$Log: fft.c,v $
|
||||
Revision 1.12 2005/02/02 07:49:55 sur
|
||||
Added interface to kiss_fft library to implement FFT for 960 transform length.
|
||||
|
||||
Revision 1.11 2004/04/02 14:56:17 danchr
|
||||
fix name clash w/ libavcodec: fft_init -> fft_initialize
|
||||
bump version number to 1.24 beta
|
||||
|
||||
Revision 1.10 2003/11/16 05:02:51 stux
|
||||
moved global tables from fft.c into hEncoder FFT_Tables. Add fft_init and fft_terminate, flowed through all necessary changes. This should remove at least one instance of a memory leak, and fix some thread-safety problems. Version update to 1.23.3
|
||||
|
||||
Revision 1.9 2003/09/07 16:48:01 knik
|
||||
reduced arrays size
|
||||
|
||||
Revision 1.8 2002/11/23 17:32:54 knik
|
||||
rfft: made xi a local variable
|
||||
|
||||
Revision 1.7 2002/08/21 16:52:25 knik
|
||||
new simplier and faster fft routine and correct real fft
|
||||
new real fft is just a complex fft wrapper so it is slower than optimal but
|
||||
by surprise it seems to be at least as fast as the old buggy function
|
||||
|
||||
*/
|
55
external/libfaac/libfaac/fft.h
vendored
Normal file
55
external/libfaac/libfaac/fft.h
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* FAAC - Freeware Advanced Audio Coder
|
||||
* $Id: fft.h,v 1.6 2005/02/02 07:50:35 sur Exp $
|
||||
* Copyright (C) 2002 Krzysztof Nikiel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _FFT_H_
|
||||
#define _FFT_H_
|
||||
|
||||
typedef float fftfloat;
|
||||
|
||||
#if defined DRM && !defined DRM_1024
|
||||
|
||||
#define MAX_FFT 10
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* cfg[Max FFT][FFT and inverse FFT] */
|
||||
void* cfg[MAX_FFT][2];
|
||||
} FFT_Tables;
|
||||
|
||||
#else /* use own FFT */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fftfloat **costbl;
|
||||
fftfloat **negsintbl;
|
||||
unsigned short **reordertbl;
|
||||
} FFT_Tables;
|
||||
|
||||
#endif /* defined DRM && !defined DRM_1024 */
|
||||
|
||||
void fft_initialize ( FFT_Tables *fft_tables );
|
||||
void fft_terminate ( FFT_Tables *fft_tables );
|
||||
|
||||
void rfft ( FFT_Tables *fft_tables, double *x, int logm );
|
||||
void fft ( FFT_Tables *fft_tables, double *xr, double *xi, int logm );
|
||||
void ffti ( FFT_Tables *fft_tables, double *xr, double *xi, int logm );
|
||||
|
||||
#endif
|
578
external/libfaac/libfaac/filtbank.c
vendored
Normal file
578
external/libfaac/libfaac/filtbank.c
vendored
Normal file
|
@ -0,0 +1,578 @@
|
|||
/************************* MPEG-2 NBC Audio Decoder **************************
|
||||
* *
|
||||
"This software module was originally developed by
|
||||
AT&T, Dolby Laboratories, Fraunhofer Gesellschaft IIS in the course of
|
||||
development of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7,
|
||||
14496-1,2 and 3. This software module is an implementation of a part of one or more
|
||||
MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4
|
||||
Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio
|
||||
standards free license to this software module or modifications thereof for use in
|
||||
hardware or software products claiming conformance to the MPEG-2 NBC/MPEG-4
|
||||
Audio standards. Those intending to use this software module in hardware or
|
||||
software products are advised that this use may infringe existing patents.
|
||||
The original developer of this software module and his/her company, the subsequent
|
||||
editors and their companies, and ISO/IEC have no liability for use of this software
|
||||
module or modifications thereof in an implementation. Copyright is not released for
|
||||
non MPEG-2 NBC/MPEG-4 Audio conforming products.The original developer
|
||||
retains full right to use the code for his/her own purpose, assign or donate the
|
||||
code to a third party and to inhibit third party from using the code for non
|
||||
MPEG-2 NBC/MPEG-4 Audio conforming products. This copyright notice must
|
||||
be included in all copies or derivative works."
|
||||
Copyright(c)1996.
|
||||
* *
|
||||
****************************************************************************/
|
||||
/*
|
||||
* $Id: filtbank.c,v 1.13 2005/02/02 07:51:12 sur Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* CHANGES:
|
||||
* 2001/01/17: menno: Added frequency cut off filter.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "coder.h"
|
||||
#include "filtbank.h"
|
||||
#include "frame.h"
|
||||
#include "fft.h"
|
||||
#include "util.h"
|
||||
|
||||
#define TWOPI 2*M_PI
|
||||
|
||||
|
||||
static void CalculateKBDWindow ( double* win, double alpha, int length );
|
||||
static double Izero ( double x);
|
||||
static void MDCT ( FFT_Tables *fft_tables, double *data, int N );
|
||||
static void IMDCT ( FFT_Tables *fft_tables, double *data, int N );
|
||||
|
||||
|
||||
|
||||
void FilterBankInit(faacEncHandle hEncoder)
|
||||
{
|
||||
unsigned int i, channel;
|
||||
|
||||
for (channel = 0; channel < hEncoder->numChannels; channel++) {
|
||||
hEncoder->freqBuff[channel] = (double*)AllocMemory(2*FRAME_LEN*sizeof(double));
|
||||
hEncoder->overlapBuff[channel] = (double*)AllocMemory(FRAME_LEN*sizeof(double));
|
||||
SetMemory(hEncoder->overlapBuff[channel], 0, FRAME_LEN*sizeof(double));
|
||||
}
|
||||
|
||||
hEncoder->sin_window_long = (double*)AllocMemory(BLOCK_LEN_LONG*sizeof(double));
|
||||
hEncoder->sin_window_short = (double*)AllocMemory(BLOCK_LEN_SHORT*sizeof(double));
|
||||
hEncoder->kbd_window_long = (double*)AllocMemory(BLOCK_LEN_LONG*sizeof(double));
|
||||
hEncoder->kbd_window_short = (double*)AllocMemory(BLOCK_LEN_SHORT*sizeof(double));
|
||||
|
||||
for( i=0; i<BLOCK_LEN_LONG; i++ )
|
||||
hEncoder->sin_window_long[i] = sin((M_PI/(2*BLOCK_LEN_LONG)) * (i + 0.5));
|
||||
for( i=0; i<BLOCK_LEN_SHORT; i++ )
|
||||
hEncoder->sin_window_short[i] = sin((M_PI/(2*BLOCK_LEN_SHORT)) * (i + 0.5));
|
||||
|
||||
CalculateKBDWindow(hEncoder->kbd_window_long, 4, BLOCK_LEN_LONG*2);
|
||||
CalculateKBDWindow(hEncoder->kbd_window_short, 6, BLOCK_LEN_SHORT*2);
|
||||
}
|
||||
|
||||
void FilterBankEnd(faacEncHandle hEncoder)
|
||||
{
|
||||
unsigned int channel;
|
||||
|
||||
for (channel = 0; channel < hEncoder->numChannels; channel++) {
|
||||
if (hEncoder->freqBuff[channel]) FreeMemory(hEncoder->freqBuff[channel]);
|
||||
if (hEncoder->overlapBuff[channel]) FreeMemory(hEncoder->overlapBuff[channel]);
|
||||
}
|
||||
|
||||
if (hEncoder->sin_window_long) FreeMemory(hEncoder->sin_window_long);
|
||||
if (hEncoder->sin_window_short) FreeMemory(hEncoder->sin_window_short);
|
||||
if (hEncoder->kbd_window_long) FreeMemory(hEncoder->kbd_window_long);
|
||||
if (hEncoder->kbd_window_short) FreeMemory(hEncoder->kbd_window_short);
|
||||
}
|
||||
|
||||
void FilterBank(faacEncHandle hEncoder,
|
||||
CoderInfo *coderInfo,
|
||||
double *p_in_data,
|
||||
double *p_out_mdct,
|
||||
double *p_overlap,
|
||||
int overlap_select)
|
||||
{
|
||||
double *p_o_buf, *first_window, *second_window;
|
||||
double *transf_buf;
|
||||
int k, i;
|
||||
int block_type = coderInfo->block_type;
|
||||
|
||||
transf_buf = (double*)AllocMemory(2*BLOCK_LEN_LONG*sizeof(double));
|
||||
|
||||
/* create / shift old values */
|
||||
/* We use p_overlap here as buffer holding the last frame time signal*/
|
||||
if(overlap_select != MNON_OVERLAPPED) {
|
||||
memcpy(transf_buf, p_overlap, FRAME_LEN*sizeof(double));
|
||||
memcpy(transf_buf+BLOCK_LEN_LONG, p_in_data, FRAME_LEN*sizeof(double));
|
||||
memcpy(p_overlap, p_in_data, FRAME_LEN*sizeof(double));
|
||||
} else {
|
||||
memcpy(transf_buf, p_in_data, 2*FRAME_LEN*sizeof(double));
|
||||
}
|
||||
|
||||
/* Window shape processing */
|
||||
if(overlap_select != MNON_OVERLAPPED) {
|
||||
switch (coderInfo->prev_window_shape) {
|
||||
case SINE_WINDOW:
|
||||
if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW))
|
||||
first_window = hEncoder->sin_window_long;
|
||||
else
|
||||
first_window = hEncoder->sin_window_short;
|
||||
break;
|
||||
case KBD_WINDOW:
|
||||
if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW))
|
||||
first_window = hEncoder->kbd_window_long;
|
||||
else
|
||||
first_window = hEncoder->kbd_window_short;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (coderInfo->window_shape){
|
||||
case SINE_WINDOW:
|
||||
if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW))
|
||||
second_window = hEncoder->sin_window_long;
|
||||
else
|
||||
second_window = hEncoder->sin_window_short;
|
||||
break;
|
||||
case KBD_WINDOW:
|
||||
if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW))
|
||||
second_window = hEncoder->kbd_window_long;
|
||||
else
|
||||
second_window = hEncoder->kbd_window_short;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Always long block and sine window for LTP */
|
||||
first_window = hEncoder->sin_window_long;
|
||||
second_window = hEncoder->sin_window_long;
|
||||
}
|
||||
|
||||
/* Set ptr to transf-Buffer */
|
||||
p_o_buf = transf_buf;
|
||||
|
||||
/* Separate action for each Block Type */
|
||||
switch (block_type) {
|
||||
case ONLY_LONG_WINDOW :
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG ; i++){
|
||||
p_out_mdct[i] = p_o_buf[i] * first_window[i];
|
||||
p_out_mdct[i+BLOCK_LEN_LONG] = p_o_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1];
|
||||
}
|
||||
MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG );
|
||||
break;
|
||||
|
||||
case LONG_SHORT_WINDOW :
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
|
||||
p_out_mdct[i] = p_o_buf[i] * first_window[i];
|
||||
memcpy(p_out_mdct+BLOCK_LEN_LONG,p_o_buf+BLOCK_LEN_LONG,NFLAT_LS*sizeof(double));
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
|
||||
p_out_mdct[i+BLOCK_LEN_LONG+NFLAT_LS] = p_o_buf[i+BLOCK_LEN_LONG+NFLAT_LS] * second_window[BLOCK_LEN_SHORT-i-1];
|
||||
SetMemory(p_out_mdct+BLOCK_LEN_LONG+NFLAT_LS+BLOCK_LEN_SHORT,0,NFLAT_LS*sizeof(double));
|
||||
MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG );
|
||||
break;
|
||||
|
||||
case SHORT_LONG_WINDOW :
|
||||
SetMemory(p_out_mdct,0,NFLAT_LS*sizeof(double));
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
|
||||
p_out_mdct[i+NFLAT_LS] = p_o_buf[i+NFLAT_LS] * first_window[i];
|
||||
memcpy(p_out_mdct+NFLAT_LS+BLOCK_LEN_SHORT,p_o_buf+NFLAT_LS+BLOCK_LEN_SHORT,NFLAT_LS*sizeof(double));
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
|
||||
p_out_mdct[i+BLOCK_LEN_LONG] = p_o_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1];
|
||||
MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG );
|
||||
break;
|
||||
|
||||
case ONLY_SHORT_WINDOW :
|
||||
p_o_buf += NFLAT_LS;
|
||||
for ( k=0; k < MAX_SHORT_WINDOWS; k++ ) {
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++ ){
|
||||
p_out_mdct[i] = p_o_buf[i] * first_window[i];
|
||||
p_out_mdct[i+BLOCK_LEN_SHORT] = p_o_buf[i+BLOCK_LEN_SHORT] * second_window[BLOCK_LEN_SHORT-i-1];
|
||||
}
|
||||
MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_SHORT );
|
||||
p_out_mdct += BLOCK_LEN_SHORT;
|
||||
p_o_buf += BLOCK_LEN_SHORT;
|
||||
first_window = second_window;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (transf_buf) FreeMemory(transf_buf);
|
||||
}
|
||||
|
||||
void IFilterBank(faacEncHandle hEncoder,
|
||||
CoderInfo *coderInfo,
|
||||
double *p_in_data,
|
||||
double *p_out_data,
|
||||
double *p_overlap,
|
||||
int overlap_select)
|
||||
{
|
||||
double *o_buf, *transf_buf, *overlap_buf;
|
||||
double *first_window, *second_window;
|
||||
|
||||
double *fp;
|
||||
int k, i;
|
||||
int block_type = coderInfo->block_type;
|
||||
|
||||
transf_buf = (double*)AllocMemory(2*BLOCK_LEN_LONG*sizeof(double));
|
||||
overlap_buf = (double*)AllocMemory(2*BLOCK_LEN_LONG*sizeof(double));
|
||||
|
||||
/* Window shape processing */
|
||||
if (overlap_select != MNON_OVERLAPPED) {
|
||||
// switch (coderInfo->prev_window_shape){
|
||||
// case SINE_WINDOW:
|
||||
if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW))
|
||||
first_window = hEncoder->sin_window_long;
|
||||
else
|
||||
first_window = hEncoder->sin_window_short;
|
||||
// break;
|
||||
// case KBD_WINDOW:
|
||||
// if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW))
|
||||
// first_window = hEncoder->kbd_window_long;
|
||||
// else
|
||||
// first_window = hEncoder->kbd_window_short;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// switch (coderInfo->window_shape){
|
||||
// case SINE_WINDOW:
|
||||
if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW))
|
||||
second_window = hEncoder->sin_window_long;
|
||||
else
|
||||
second_window = hEncoder->sin_window_short;
|
||||
// break;
|
||||
// case KBD_WINDOW:
|
||||
// if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW))
|
||||
// second_window = hEncoder->kbd_window_long;
|
||||
// else
|
||||
// second_window = hEncoder->kbd_window_short;
|
||||
// break;
|
||||
// }
|
||||
} else {
|
||||
/* Always long block and sine window for LTP */
|
||||
first_window = hEncoder->sin_window_long;
|
||||
second_window = hEncoder->sin_window_long;
|
||||
}
|
||||
|
||||
/* Assemble overlap buffer */
|
||||
memcpy(overlap_buf,p_overlap,BLOCK_LEN_LONG*sizeof(double));
|
||||
o_buf = overlap_buf;
|
||||
|
||||
/* Separate action for each Block Type */
|
||||
switch( block_type ) {
|
||||
case ONLY_LONG_WINDOW :
|
||||
memcpy(transf_buf, p_in_data,BLOCK_LEN_LONG*sizeof(double));
|
||||
IMDCT( &hEncoder->fft_tables, transf_buf, 2*BLOCK_LEN_LONG );
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
|
||||
transf_buf[i] *= first_window[i];
|
||||
if (overlap_select != MNON_OVERLAPPED) {
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG; i++ ){
|
||||
o_buf[i] += transf_buf[i];
|
||||
o_buf[i+BLOCK_LEN_LONG] = transf_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1];
|
||||
}
|
||||
} else { /* overlap_select == NON_OVERLAPPED */
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG; i++ )
|
||||
transf_buf[i+BLOCK_LEN_LONG] *= second_window[BLOCK_LEN_LONG-i-1];
|
||||
}
|
||||
break;
|
||||
|
||||
case LONG_SHORT_WINDOW :
|
||||
memcpy(transf_buf, p_in_data,BLOCK_LEN_LONG*sizeof(double));
|
||||
IMDCT( &hEncoder->fft_tables, transf_buf, 2*BLOCK_LEN_LONG );
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
|
||||
transf_buf[i] *= first_window[i];
|
||||
if (overlap_select != MNON_OVERLAPPED) {
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG; i++ )
|
||||
o_buf[i] += transf_buf[i];
|
||||
memcpy(o_buf+BLOCK_LEN_LONG,transf_buf+BLOCK_LEN_LONG,NFLAT_LS*sizeof(double));
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
|
||||
o_buf[i+BLOCK_LEN_LONG+NFLAT_LS] = transf_buf[i+BLOCK_LEN_LONG+NFLAT_LS] * second_window[BLOCK_LEN_SHORT-i-1];
|
||||
SetMemory(o_buf+BLOCK_LEN_LONG+NFLAT_LS+BLOCK_LEN_SHORT,0,NFLAT_LS*sizeof(double));
|
||||
} else { /* overlap_select == NON_OVERLAPPED */
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
|
||||
transf_buf[i+BLOCK_LEN_LONG+NFLAT_LS] *= second_window[BLOCK_LEN_SHORT-i-1];
|
||||
SetMemory(transf_buf+BLOCK_LEN_LONG+NFLAT_LS+BLOCK_LEN_SHORT,0,NFLAT_LS*sizeof(double));
|
||||
}
|
||||
break;
|
||||
|
||||
case SHORT_LONG_WINDOW :
|
||||
memcpy(transf_buf, p_in_data,BLOCK_LEN_LONG*sizeof(double));
|
||||
IMDCT( &hEncoder->fft_tables, transf_buf, 2*BLOCK_LEN_LONG );
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
|
||||
transf_buf[i+NFLAT_LS] *= first_window[i];
|
||||
if (overlap_select != MNON_OVERLAPPED) {
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT; i++ )
|
||||
o_buf[i+NFLAT_LS] += transf_buf[i+NFLAT_LS];
|
||||
memcpy(o_buf+BLOCK_LEN_SHORT+NFLAT_LS,transf_buf+BLOCK_LEN_SHORT+NFLAT_LS,NFLAT_LS*sizeof(double));
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
|
||||
o_buf[i+BLOCK_LEN_LONG] = transf_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1];
|
||||
} else { /* overlap_select == NON_OVERLAPPED */
|
||||
SetMemory(transf_buf,0,NFLAT_LS*sizeof(double));
|
||||
for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
|
||||
transf_buf[i+BLOCK_LEN_LONG] *= second_window[BLOCK_LEN_LONG-i-1];
|
||||
}
|
||||
break;
|
||||
|
||||
case ONLY_SHORT_WINDOW :
|
||||
if (overlap_select != MNON_OVERLAPPED) {
|
||||
fp = o_buf + NFLAT_LS;
|
||||
} else { /* overlap_select == NON_OVERLAPPED */
|
||||
fp = transf_buf;
|
||||
}
|
||||
for ( k=0; k < MAX_SHORT_WINDOWS; k++ ) {
|
||||
memcpy(transf_buf,p_in_data,BLOCK_LEN_SHORT*sizeof(double));
|
||||
IMDCT( &hEncoder->fft_tables, transf_buf, 2*BLOCK_LEN_SHORT );
|
||||
p_in_data += BLOCK_LEN_SHORT;
|
||||
if (overlap_select != MNON_OVERLAPPED) {
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++){
|
||||
transf_buf[i] *= first_window[i];
|
||||
fp[i] += transf_buf[i];
|
||||
fp[i+BLOCK_LEN_SHORT] = transf_buf[i+BLOCK_LEN_SHORT] * second_window[BLOCK_LEN_SHORT-i-1];
|
||||
}
|
||||
fp += BLOCK_LEN_SHORT;
|
||||
} else { /* overlap_select == NON_OVERLAPPED */
|
||||
for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++){
|
||||
fp[i] *= first_window[i];
|
||||
fp[i+BLOCK_LEN_SHORT] *= second_window[BLOCK_LEN_SHORT-i-1];
|
||||
}
|
||||
fp += 2*BLOCK_LEN_SHORT;
|
||||
}
|
||||
first_window = second_window;
|
||||
}
|
||||
SetMemory(o_buf+BLOCK_LEN_LONG+NFLAT_LS+BLOCK_LEN_SHORT,0,NFLAT_LS*sizeof(double));
|
||||
break;
|
||||
}
|
||||
|
||||
if (overlap_select != MNON_OVERLAPPED)
|
||||
memcpy(p_out_data,o_buf,BLOCK_LEN_LONG*sizeof(double));
|
||||
else /* overlap_select == NON_OVERLAPPED */
|
||||
memcpy(p_out_data,transf_buf,2*BLOCK_LEN_LONG*sizeof(double));
|
||||
|
||||
/* save unused output data */
|
||||
memcpy(p_overlap,o_buf+BLOCK_LEN_LONG,BLOCK_LEN_LONG*sizeof(double));
|
||||
|
||||
if (overlap_buf) FreeMemory(overlap_buf);
|
||||
if (transf_buf) FreeMemory(transf_buf);
|
||||
}
|
||||
|
||||
void specFilter(double *freqBuff,
|
||||
int sampleRate,
|
||||
int lowpassFreq,
|
||||
int specLen
|
||||
)
|
||||
{
|
||||
int lowpass,xlowpass;
|
||||
|
||||
/* calculate the last line which is not zero */
|
||||
lowpass = (lowpassFreq * specLen) / (sampleRate>>1) + 1;
|
||||
xlowpass = (lowpass < specLen) ? lowpass : specLen ;
|
||||
|
||||
SetMemory(freqBuff+xlowpass,0,(specLen-xlowpass)*sizeof(double));
|
||||
}
|
||||
|
||||
static double Izero(double x)
|
||||
{
|
||||
const double IzeroEPSILON = 1E-41; /* Max error acceptable in Izero */
|
||||
double sum, u, halfx, temp;
|
||||
int n;
|
||||
|
||||
sum = u = n = 1;
|
||||
halfx = x/2.0;
|
||||
do {
|
||||
temp = halfx/(double)n;
|
||||
n += 1;
|
||||
temp *= temp;
|
||||
u *= temp;
|
||||
sum += u;
|
||||
} while (u >= IzeroEPSILON*sum);
|
||||
|
||||
return(sum);
|
||||
}
|
||||
|
||||
static void CalculateKBDWindow(double* win, double alpha, int length)
|
||||
{
|
||||
int i;
|
||||
double IBeta;
|
||||
double tmp;
|
||||
double sum = 0.0;
|
||||
|
||||
alpha *= M_PI;
|
||||
IBeta = 1.0/Izero(alpha);
|
||||
|
||||
/* calculate lower half of Kaiser Bessel window */
|
||||
for(i=0; i<(length>>1); i++) {
|
||||
tmp = 4.0*(double)i/(double)length - 1.0;
|
||||
win[i] = Izero(alpha*sqrt(1.0-tmp*tmp))*IBeta;
|
||||
sum += win[i];
|
||||
}
|
||||
|
||||
sum = 1.0/sum;
|
||||
tmp = 0.0;
|
||||
|
||||
/* calculate lower half of window */
|
||||
for(i=0; i<(length>>1); i++) {
|
||||
tmp += win[i];
|
||||
win[i] = sqrt(tmp*sum);
|
||||
}
|
||||
}
|
||||
|
||||
static void MDCT( FFT_Tables *fft_tables, double *data, int N )
|
||||
{
|
||||
double *xi, *xr;
|
||||
double tempr, tempi, c, s, cold, cfreq, sfreq; /* temps for pre and post twiddle */
|
||||
double freq = TWOPI / N;
|
||||
double cosfreq8, sinfreq8;
|
||||
int i, n;
|
||||
|
||||
xi = (double*)AllocMemory((N >> 2)*sizeof(double));
|
||||
xr = (double*)AllocMemory((N >> 2)*sizeof(double));
|
||||
|
||||
/* prepare for recurrence relation in pre-twiddle */
|
||||
cfreq = cos (freq);
|
||||
sfreq = sin (freq);
|
||||
cosfreq8 = cos (freq * 0.125);
|
||||
sinfreq8 = sin (freq * 0.125);
|
||||
c = cosfreq8;
|
||||
s = sinfreq8;
|
||||
|
||||
for (i = 0; i < (N >> 2); i++) {
|
||||
/* calculate real and imaginary parts of g(n) or G(p) */
|
||||
n = (N >> 1) - 1 - 2 * i;
|
||||
|
||||
if (i < (N >> 3))
|
||||
tempr = data [(N >> 2) + n] + data [N + (N >> 2) - 1 - n]; /* use second form of e(n) for n = N / 2 - 1 - 2i */
|
||||
else
|
||||
tempr = data [(N >> 2) + n] - data [(N >> 2) - 1 - n]; /* use first form of e(n) for n = N / 2 - 1 - 2i */
|
||||
|
||||
n = 2 * i;
|
||||
if (i < (N >> 3))
|
||||
tempi = data [(N >> 2) + n] - data [(N >> 2) - 1 - n]; /* use first form of e(n) for n=2i */
|
||||
else
|
||||
tempi = data [(N >> 2) + n] + data [N + (N >> 2) - 1 - n]; /* use second form of e(n) for n=2i*/
|
||||
|
||||
/* calculate pre-twiddled FFT input */
|
||||
xr[i] = tempr * c + tempi * s;
|
||||
xi[i] = tempi * c - tempr * s;
|
||||
|
||||
/* use recurrence to prepare cosine and sine for next value of i */
|
||||
cold = c;
|
||||
c = c * cfreq - s * sfreq;
|
||||
s = s * cfreq + cold * sfreq;
|
||||
}
|
||||
|
||||
/* Perform in-place complex FFT of length N/4 */
|
||||
switch (N) {
|
||||
case BLOCK_LEN_SHORT * 2:
|
||||
fft( fft_tables, xr, xi, 6);
|
||||
break;
|
||||
case BLOCK_LEN_LONG * 2:
|
||||
fft( fft_tables, xr, xi, 9);
|
||||
}
|
||||
|
||||
/* prepare for recurrence relations in post-twiddle */
|
||||
c = cosfreq8;
|
||||
s = sinfreq8;
|
||||
|
||||
/* post-twiddle FFT output and then get output data */
|
||||
for (i = 0; i < (N >> 2); i++) {
|
||||
/* get post-twiddled FFT output */
|
||||
tempr = 2. * (xr[i] * c + xi[i] * s);
|
||||
tempi = 2. * (xi[i] * c - xr[i] * s);
|
||||
|
||||
/* fill in output values */
|
||||
data [2 * i] = -tempr; /* first half even */
|
||||
data [(N >> 1) - 1 - 2 * i] = tempi; /* first half odd */
|
||||
data [(N >> 1) + 2 * i] = -tempi; /* second half even */
|
||||
data [N - 1 - 2 * i] = tempr; /* second half odd */
|
||||
|
||||
/* use recurrence to prepare cosine and sine for next value of i */
|
||||
cold = c;
|
||||
c = c * cfreq - s * sfreq;
|
||||
s = s * cfreq + cold * sfreq;
|
||||
}
|
||||
|
||||
if (xr) FreeMemory(xr);
|
||||
if (xi) FreeMemory(xi);
|
||||
}
|
||||
|
||||
static void IMDCT( FFT_Tables *fft_tables, double *data, int N)
|
||||
{
|
||||
double *xi, *xr;
|
||||
double tempr, tempi, c, s, cold, cfreq, sfreq; /* temps for pre and post twiddle */
|
||||
double freq = 2.0 * M_PI / N;
|
||||
double fac, cosfreq8, sinfreq8;
|
||||
int i;
|
||||
|
||||
xi = (double*)AllocMemory((N >> 2)*sizeof(double));
|
||||
xr = (double*)AllocMemory((N >> 2)*sizeof(double));
|
||||
|
||||
/* Choosing to allocate 2/N factor to Inverse Xform! */
|
||||
fac = 2. / N; /* remaining 2/N from 4/N IFFT factor */
|
||||
|
||||
/* prepare for recurrence relation in pre-twiddle */
|
||||
cfreq = cos (freq);
|
||||
sfreq = sin (freq);
|
||||
cosfreq8 = cos (freq * 0.125);
|
||||
sinfreq8 = sin (freq * 0.125);
|
||||
c = cosfreq8;
|
||||
s = sinfreq8;
|
||||
|
||||
for (i = 0; i < (N >> 2); i++) {
|
||||
/* calculate real and imaginary parts of g(n) or G(p) */
|
||||
tempr = -data[2 * i];
|
||||
tempi = data[(N >> 1) - 1 - 2 * i];
|
||||
|
||||
/* calculate pre-twiddled FFT input */
|
||||
xr[i] = tempr * c - tempi * s;
|
||||
xi[i] = tempi * c + tempr * s;
|
||||
|
||||
/* use recurrence to prepare cosine and sine for next value of i */
|
||||
cold = c;
|
||||
c = c * cfreq - s * sfreq;
|
||||
s = s * cfreq + cold * sfreq;
|
||||
}
|
||||
|
||||
/* Perform in-place complex IFFT of length N/4 */
|
||||
switch (N) {
|
||||
case BLOCK_LEN_SHORT * 2:
|
||||
ffti( fft_tables, xr, xi, 6);
|
||||
break;
|
||||
case BLOCK_LEN_LONG * 2:
|
||||
ffti( fft_tables, xr, xi, 9);
|
||||
}
|
||||
|
||||
/* prepare for recurrence relations in post-twiddle */
|
||||
c = cosfreq8;
|
||||
s = sinfreq8;
|
||||
|
||||
/* post-twiddle FFT output and then get output data */
|
||||
for (i = 0; i < (N >> 2); i++) {
|
||||
|
||||
/* get post-twiddled FFT output */
|
||||
tempr = fac * (xr[i] * c - xi[i] * s);
|
||||
tempi = fac * (xi[i] * c + xr[i] * s);
|
||||
|
||||
/* fill in output values */
|
||||
data [(N >> 1) + (N >> 2) - 1 - 2 * i] = tempr;
|
||||
if (i < (N >> 3))
|
||||
data [(N >> 1) + (N >> 2) + 2 * i] = tempr;
|
||||
else
|
||||
data [2 * i - (N >> 2)] = -tempr;
|
||||
|
||||
data [(N >> 2) + 2 * i] = tempi;
|
||||
if (i < (N >> 3))
|
||||
data [(N >> 2) - 1 - 2 * i] = -tempi;
|
||||
else
|
||||
data [(N >> 2) + N - 1 - 2*i] = tempi;
|
||||
|
||||
/* use recurrence to prepare cosine and sine for next value of i */
|
||||
cold = c;
|
||||
c = c * cfreq - s * sfreq;
|
||||
s = s * cfreq + cold * sfreq;
|
||||
}
|
||||
|
||||
if (xr) FreeMemory(xr);
|
||||
if (xi) FreeMemory(xi);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user