Compare commits
1935 Commits
v0.14.0-be
...
dependabot
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b652ce6bb3 | ||
![]() |
41e5c12e5b | ||
![]() |
8307fe31aa | ||
![]() |
1f061a8e73 | ||
![]() |
55d6383234 | ||
![]() |
caa187e4ed | ||
![]() |
4331ed0d7b | ||
![]() |
08309793d4 | ||
![]() |
c7a4e6bcc4 | ||
![]() |
c94446a472 | ||
![]() |
17b6128314 | ||
![]() |
117a878533 | ||
![]() |
ff5ebcf94d | ||
![]() |
24c519f032 | ||
![]() |
90fbb77ee0 | ||
![]() |
9f1d8b0e31 | ||
![]() |
875d20b195 | ||
![]() |
48056ac15c | ||
![]() |
993459152b | ||
![]() |
8430fbc705 | ||
![]() |
f7c4ff12f7 | ||
![]() |
8f0be18422 | ||
![]() |
28e3aa39f0 | ||
![]() |
16c88fa8ac | ||
![]() |
1b6c246a44 | ||
![]() |
e8b2828ca0 | ||
![]() |
923412ec1c | ||
![]() |
8b85cd816e | ||
![]() |
bebe99d9b8 | ||
![]() |
a08fda62f8 | ||
![]() |
9fdce80729 | ||
![]() |
12f8c3feac | ||
![]() |
b6552987b0 | ||
![]() |
c207009d8a | ||
![]() |
e6cbc93703 | ||
![]() |
b8b07ee6e1 | ||
![]() |
082867447b | ||
![]() |
8b293449f9 | ||
![]() |
2f209b2cf4 | ||
![]() |
9a22404015 | ||
![]() |
2c4a043dbb | ||
![]() |
b23355da53 | ||
![]() |
90db2d57b3 | ||
![]() |
652fdc6a38 | ||
![]() |
7e2f5a3017 | ||
![]() |
2f99a17e64 | ||
![]() |
2bc92cce81 | ||
![]() |
7f7eefef7f | ||
![]() |
bdb7a18602 | ||
![]() |
318457113b | ||
![]() |
e4d5f1f94e | ||
![]() |
0e61d3f153 | ||
![]() |
cd519ed1ad | ||
![]() |
2a860bd85e | ||
![]() |
a7bbca5014 | ||
![]() |
dc96940eb9 | ||
![]() |
1408abb050 | ||
![]() |
9c5e560668 | ||
![]() |
b8fd0a2b31 | ||
![]() |
61d3b370b1 | ||
![]() |
8295773146 | ||
![]() |
8412b33468 | ||
![]() |
508a2ea4ba | ||
![]() |
e7048feff1 | ||
![]() |
2c0416348f | ||
![]() |
94134970df | ||
![]() |
80dbb9e38e | ||
![]() |
fc6446b9e6 | ||
![]() |
b1ec055aaa | ||
![]() |
5a26d7b029 | ||
![]() |
6f9b38819a | ||
![]() |
d679c42160 | ||
![]() |
ad6da29ea2 | ||
![]() |
a9852d62f4 | ||
![]() |
fa2e583fd1 | ||
![]() |
55cc4b55fe | ||
![]() |
db765f2a60 | ||
![]() |
e06127947d | ||
![]() |
96d84ab74f | ||
![]() |
483639df25 | ||
![]() |
83696c60fd | ||
![]() |
b24726bc80 | ||
![]() |
892560a123 | ||
![]() |
6d9ef1b439 | ||
![]() |
b1ec1d20af | ||
![]() |
9e7ed4daa8 | ||
![]() |
c79d9d8d86 | ||
![]() |
251b029d6e | ||
![]() |
68f806bb61 | ||
![]() |
c05e260ae9 | ||
![]() |
1efff67e32 | ||
![]() |
26178444f3 | ||
![]() |
4914029a50 | ||
![]() |
975c8485f9 | ||
![]() |
bafdab9d67 | ||
![]() |
5f34a18905 | ||
![]() |
6cd1d1f205 | ||
![]() |
03fe054078 | ||
![]() |
2d4a0cc584 | ||
![]() |
ff0430964c | ||
![]() |
b08db4913f | ||
![]() |
c74e86dff2 | ||
![]() |
81d7c47129 | ||
![]() |
41ed013cc4 | ||
![]() |
751678c845 | ||
![]() |
ed1e3a7c9a | ||
![]() |
ba650af6f2 | ||
![]() |
fad28a764c | ||
![]() |
7c7ff49b90 | ||
![]() |
15729e0f19 | ||
![]() |
037c4d1cc0 | ||
![]() |
1613499218 | ||
![]() |
205fdf3ae3 | ||
![]() |
f46f8a2160 | ||
![]() |
880902cdd7 | ||
![]() |
c5ed95ec52 | ||
![]() |
751de141d5 | ||
![]() |
0eb441fe50 | ||
![]() |
7566aecb0b | ||
![]() |
60714a733e | ||
![]() |
d7f7cd7be1 | ||
![]() |
6591210050 | ||
![]() |
fd6e7afea9 | ||
![]() |
b781f06f9c | ||
![]() |
7e7b3288a8 | ||
![]() |
a8b7e5dd24 | ||
![]() |
6505ae5fb5 | ||
![]() |
fe3eb24dfe | ||
![]() |
e664cb2285 | ||
![]() |
62047c80d5 | ||
![]() |
198e53bd42 | ||
![]() |
f7ed8b4cab | ||
![]() |
bd255362d6 | ||
![]() |
55160f9235 | ||
![]() |
8e7f0cfd51 | ||
![]() |
9fd07bde48 | ||
![]() |
efe707510e | ||
![]() |
4cca09410f | ||
![]() |
cc270e7d1e | ||
![]() |
bba22bd456 | ||
![]() |
ecfe4448c8 | ||
![]() |
4d0982e9b0 | ||
![]() |
674abaee1f | ||
![]() |
a9c4aff0b1 | ||
![]() |
f7ff452992 | ||
![]() |
e35a904df4 | ||
![]() |
364bff447b | ||
![]() |
d5096a6330 | ||
![]() |
1a8b2dcbe9 | ||
![]() |
b777c2cf73 | ||
![]() |
2214bf611f | ||
![]() |
40af34ee11 | ||
![]() |
6e4fc8611d | ||
![]() |
732b1a4a6e | ||
![]() |
269ac067f5 | ||
![]() |
674c066837 | ||
![]() |
54afe41ed0 | ||
![]() |
ee626d21f8 | ||
![]() |
ef74605e45 | ||
![]() |
d4e939b663 | ||
![]() |
1004f73493 | ||
![]() |
e3dc53f2e6 | ||
![]() |
35eb08cbb2 | ||
![]() |
033ec2e0e7 | ||
![]() |
0402efbf7c | ||
![]() |
88f7959d7f | ||
![]() |
ed86430709 | ||
![]() |
2bdfe1316c | ||
![]() |
b86e6e484f | ||
![]() |
9af7246b0b | ||
![]() |
3a1e1d0841 | ||
![]() |
a478c38f8a | ||
![]() |
c7231648eb | ||
![]() |
92555eb835 | ||
![]() |
a2ba4e4e39 | ||
![]() |
e9dc30235b | ||
![]() |
16b7f7f6e7 | ||
![]() |
d78b6e528b | ||
![]() |
281c461647 | ||
![]() |
667c302a7d | ||
![]() |
0febc4d456 | ||
![]() |
ad694f5511 | ||
![]() |
fa6956c46e | ||
![]() |
398a3a7b95 | ||
![]() |
b5aa1b2c21 | ||
![]() |
d3af748366 | ||
![]() |
195f705616 | ||
![]() |
6c3f99150c | ||
![]() |
f62feeb50c | ||
![]() |
0dda37ac43 | ||
![]() |
22e981c38c | ||
![]() |
ed9d031e80 | ||
![]() |
c260642604 | ||
![]() |
4fcb1ea7ac | ||
![]() |
4347402fcc | ||
![]() |
1636fee36a | ||
![]() |
5af8fbac51 | ||
![]() |
b036eb612a | ||
![]() |
8be82b63f4 | ||
![]() |
1241e27aac | ||
![]() |
02ee37ab55 | ||
![]() |
e0f695d8b1 | ||
![]() |
819e0a0bf9 | ||
![]() |
2a3065eb67 | ||
![]() |
db45dd3698 | ||
![]() |
6136504128 | ||
![]() |
47af0b63c5 | ||
![]() |
8bfa4be42f | ||
![]() |
b8af90331b | ||
![]() |
95131541c5 | ||
![]() |
a88760efa1 | ||
![]() |
ee48d6782d | ||
![]() |
dbceb4dcc7 | ||
![]() |
9dd7ead462 | ||
![]() |
4fe246f472 | ||
![]() |
539c760953 | ||
![]() |
7cf439e010 | ||
![]() |
f39475a383 | ||
![]() |
1be84d6833 | ||
![]() |
8a01643acf | ||
![]() |
efeb089ff8 | ||
![]() |
f83e528461 | ||
![]() |
51d1bc883b | ||
![]() |
af590310fc | ||
![]() |
8242fc0077 | ||
![]() |
bb2f1ca41a | ||
![]() |
1519ad7945 | ||
![]() |
cfff0fa3ee | ||
![]() |
6b8a140c89 | ||
![]() |
f97aa00733 | ||
![]() |
e0689027a1 | ||
![]() |
747dac8f81 | ||
![]() |
62e8260131 | ||
![]() |
cdb8b4542a | ||
![]() |
acab9c2e5b | ||
![]() |
4540165703 | ||
![]() |
a4ebee3ead | ||
![]() |
cbd71b25e2 | ||
![]() |
a0e657e207 | ||
![]() |
f589ee0f20 | ||
![]() |
3a42b4439c | ||
![]() |
8c7cf1fc7e | ||
![]() |
ac159f114c | ||
![]() |
e256402e8c | ||
![]() |
05152b0676 | ||
![]() |
dc20903711 | ||
![]() |
2236ecf23f | ||
![]() |
6e3b40eaee | ||
![]() |
664a6fd0cb | ||
![]() |
80144fe524 | ||
![]() |
b003cecd73 | ||
![]() |
2b185a1105 | ||
![]() |
361014f01c | ||
![]() |
75e33d8a56 | ||
![]() |
8f4b5b4bdb | ||
![]() |
95cea06dd3 | ||
![]() |
9fb09408d1 | ||
![]() |
ec2543c23f | ||
![]() |
e92267d7e2 | ||
![]() |
8e254aa1f0 | ||
![]() |
acf32e1a1e | ||
![]() |
d27e8c1bbf | ||
![]() |
33f3ea3b59 | ||
![]() |
83e9ae616a | ||
![]() |
353ee1228c | ||
![]() |
0309090852 | ||
![]() |
152d9ed4a0 | ||
![]() |
ba20b61c43 | ||
![]() |
b45f642868 | ||
![]() |
9ed7ccab75 | ||
![]() |
ceced7cc91 | ||
![]() |
1db26cb41e | ||
![]() |
5a49d1f73c | ||
![]() |
6840415b6c | ||
![]() |
856aab8e6e | ||
![]() |
ccbaa74a8b | ||
![]() |
6671984e5a | ||
![]() |
7740b08bd9 | ||
![]() |
dace88bfce | ||
![]() |
8e663413bb | ||
![]() |
cc18d7f786 | ||
![]() |
3cf86767f1 | ||
![]() |
92417a1b9c | ||
![]() |
2cf8dd693c | ||
![]() |
1f3755e45d | ||
![]() |
7c1681e344 | ||
![]() |
6ecc631486 | ||
![]() |
21ab164bfe | ||
![]() |
fcf3824124 | ||
![]() |
1add72884a | ||
![]() |
e9e3c481b2 | ||
![]() |
fa1b88097b | ||
![]() |
10160fb3b5 | ||
![]() |
20104761e8 | ||
![]() |
d071325ca7 | ||
![]() |
55e5a55fa2 | ||
![]() |
8719216fa6 | ||
![]() |
22478df4d6 | ||
![]() |
3609b41217 | ||
![]() |
28f816b49a | ||
![]() |
528f0d2b1f | ||
![]() |
f925154b8a | ||
![]() |
13fb7bc260 | ||
![]() |
ceeb6543f5 | ||
![]() |
cf62bee170 | ||
![]() |
ec6c04e49a | ||
![]() |
da0248db15 | ||
![]() |
542bf05bb8 | ||
![]() |
e1ee6f010f | ||
![]() |
3327be05ea | ||
![]() |
9c2ba152e1 | ||
![]() |
7c8164aa99 | ||
![]() |
847b03e71b | ||
![]() |
0d5a49ab82 | ||
![]() |
2f4d7353f4 | ||
![]() |
ef060b97ca | ||
![]() |
e832bb4bad | ||
![]() |
4deccf08a1 | ||
![]() |
a6b80c0f9c | ||
![]() |
1caf8b97c4 | ||
![]() |
faadea8e1f | ||
![]() |
4b57e5e265 | ||
![]() |
40ab7d6c38 | ||
![]() |
937459be47 | ||
![]() |
13b760346a | ||
![]() |
7ce26087f7 | ||
![]() |
b1a65c88e8 | ||
![]() |
765a28d812 | ||
![]() |
1c75ff59f1 | ||
![]() |
ac7fb29b32 | ||
![]() |
b77e6f5ebc | ||
![]() |
3f8ec72336 | ||
![]() |
0b9997015a | ||
![]() |
2c7b71b16e | ||
![]() |
6dc36fcbb4 | ||
![]() |
2385c403ee | ||
![]() |
cf1d50be30 | ||
![]() |
723553edb7 | ||
![]() |
53ff33135b | ||
![]() |
4ebc4f6d21 | ||
![]() |
e1340443f5 | ||
![]() |
4dc526761c | ||
![]() |
dc187eee1c | ||
![]() |
b7dbcce6e5 | ||
![]() |
06539c925c | ||
![]() |
addb4e6891 | ||
![]() |
fb290c411b | ||
![]() |
89db960c05 | ||
![]() |
2cde58037d | ||
![]() |
d1be614a10 | ||
![]() |
93c7c8c518 | ||
![]() |
c83a35d090 | ||
![]() |
d31a4e3443 | ||
![]() |
c2f8de94e8 | ||
![]() |
f46560d2bf | ||
![]() |
a1acb504ee | ||
![]() |
3d79eef227 | ||
![]() |
efe0d2a931 | ||
![]() |
cbd5bdfd88 | ||
![]() |
6f2e6c4cb2 | ||
![]() |
84f48ee3eb | ||
![]() |
49793aa655 | ||
![]() |
4869f46ab6 | ||
![]() |
5e5beb9837 | ||
![]() |
f7184c8ed5 | ||
![]() |
2e1b81b380 | ||
![]() |
30cf274815 | ||
![]() |
b15c799d8c | ||
![]() |
b6b3178e3d | ||
![]() |
334b6670e1 | ||
![]() |
5fc030c3f6 | ||
![]() |
ca3afa8ac4 | ||
![]() |
878f401ad2 | ||
![]() |
99f9c1529d | ||
![]() |
369e6ba2c2 | ||
![]() |
8254602449 | ||
![]() |
a0a5aad3c2 | ||
![]() |
f107aa3cea | ||
![]() |
cd7b9b604e | ||
![]() |
1bbc8823da | ||
![]() |
30de45a6f4 | ||
![]() |
f9e5350d5a | ||
![]() |
1471491124 | ||
![]() |
c1da7128da | ||
![]() |
f33468767e | ||
![]() |
76fbc103b0 | ||
![]() |
972206eb0f | ||
![]() |
b5067c07f8 | ||
![]() |
c3410cd13e | ||
![]() |
d18f2282c8 | ||
![]() |
23b32cbacf | ||
![]() |
21e9b2f2ce | ||
![]() |
92a0dad2c2 | ||
![]() |
4f4c8a4fb9 | ||
![]() |
898d1de875 | ||
![]() |
0b7a33d670 | ||
![]() |
d697e4f354 | ||
![]() |
4ad1f6e610 | ||
![]() |
072d9fc111 | ||
![]() |
9653aead10 | ||
![]() |
e910f5c97c | ||
![]() |
146de123b9 | ||
![]() |
2586b8d299 | ||
![]() |
24fd95cff4 | ||
![]() |
7aa57ebcae | ||
![]() |
d5ce0ba73e | ||
![]() |
0c92c3ccfa | ||
![]() |
480072b22d | ||
![]() |
455423e7f2 | ||
![]() |
6d5fb65a68 | ||
![]() |
eb8eee038f | ||
![]() |
7680b050b4 | ||
![]() |
60923ac1e3 | ||
![]() |
1763dba9c2 | ||
![]() |
ca1c98eab8 | ||
![]() |
3eb3797bc5 | ||
![]() |
4a94b43e52 | ||
![]() |
f81ac43be6 | ||
![]() |
4c8f4ef9fa | ||
![]() |
4b72c86e77 | ||
![]() |
d574d1edae | ||
![]() |
d96efdbf2e | ||
![]() |
0d78aca388 | ||
![]() |
c0b2693c5b | ||
![]() |
39ab6c8a10 | ||
![]() |
0dd3713af8 | ||
![]() |
52460a8fbb | ||
![]() |
fea9901ae5 | ||
![]() |
4db703cc3d | ||
![]() |
b63a3d327d | ||
![]() |
5b32ec4fbd | ||
![]() |
12a80f5713 | ||
![]() |
598520b5c2 | ||
![]() |
89e5f60fab | ||
![]() |
aa7c9f441f | ||
![]() |
2aaf96d043 | ||
![]() |
b7d705a028 | ||
![]() |
68688a6c23 | ||
![]() |
1fac827dde | ||
![]() |
a1048654ee | ||
![]() |
f75e55ee74 | ||
![]() |
3bda638678 | ||
![]() |
5cf98824f5 | ||
![]() |
687e118b58 | ||
![]() |
95daf0ba05 | ||
![]() |
213dc97c17 | ||
![]() |
ee1db240d7 | ||
![]() |
79655379be | ||
![]() |
f29cf43f52 | ||
![]() |
cd54a81150 | ||
![]() |
178117183e | ||
![]() |
d69916694b | ||
![]() |
fc608b31d7 | ||
![]() |
9ffa7f140c | ||
![]() |
6563f78ab0 | ||
![]() |
4339f26ded | ||
![]() |
86a3e31edf | ||
![]() |
7238b3ea22 | ||
![]() |
ea576e7468 | ||
![]() |
5593495abd | ||
![]() |
fd96cd5dae | ||
![]() |
e0c1fea2ac | ||
![]() |
f97629433d | ||
![]() |
aabd5b0077 | ||
![]() |
623bc72633 | ||
![]() |
f3a0d519fb | ||
![]() |
cc368dd20f | ||
![]() |
8a9ebe9292 | ||
![]() |
4ff81d5877 | ||
![]() |
fe571dc217 | ||
![]() |
42cae5d9ee | ||
![]() |
ce2b60a4df | ||
![]() |
02f75d3b1f | ||
![]() |
c935a76a45 | ||
![]() |
d727adddde | ||
![]() |
2d586eeeb7 | ||
![]() |
25cc2f31d4 | ||
![]() |
4a21b2f16d | ||
![]() |
99e7533de2 | ||
![]() |
03768e0050 | ||
![]() |
ed43df9c13 | ||
![]() |
460e291bf1 | ||
![]() |
dba9206898 | ||
![]() |
af5a9e7634 | ||
![]() |
afaac33c60 | ||
![]() |
f141b585bc | ||
![]() |
9de7f80727 | ||
![]() |
2101b1f91d | ||
![]() |
2b5a30e23b | ||
![]() |
dd6114586c | ||
![]() |
d508a8b5fe | ||
![]() |
feb40e9d05 | ||
![]() |
2548af13b9 | ||
![]() |
547c61f54c | ||
![]() |
34e92ef4ae | ||
![]() |
dbf440b0c7 | ||
![]() |
321fd136c0 | ||
![]() |
c9708102a9 | ||
![]() |
85d8d7b136 | ||
![]() |
b0e6a64bd0 | ||
![]() |
2af1d22643 | ||
![]() |
c026060ff3 | ||
![]() |
8a117de87e | ||
![]() |
a43f87c477 | ||
![]() |
15c7a4074b | ||
![]() |
ca650a29a1 | ||
![]() |
0896df6500 | ||
![]() |
01998dfb70 | ||
![]() |
cb1cdcc814 | ||
![]() |
63473b0b82 | ||
![]() |
ee51326d35 | ||
![]() |
2ada0d22cb | ||
![]() |
81f5f362a9 | ||
![]() |
27914fc3b8 | ||
![]() |
c11ca42fb5 | ||
![]() |
9b7d4d0a8f | ||
![]() |
cbdac9ece5 | ||
![]() |
948b087d3c | ||
![]() |
63f9689b0e | ||
![]() |
6969a7fd47 | ||
![]() |
8274b733da | ||
![]() |
858c1241db | ||
![]() |
c16e536b46 | ||
![]() |
49c6073de6 | ||
![]() |
2a8b62acb1 | ||
![]() |
37d40558b7 | ||
![]() |
afe513336c | ||
![]() |
8a143b4284 | ||
![]() |
717517aeb5 | ||
![]() |
f4d5ebf4db | ||
![]() |
b18572a3b6 | ||
![]() |
b10615aef1 | ||
![]() |
5d13925d2b | ||
![]() |
ebae6cb1ed | ||
![]() |
2f9b373c1a | ||
![]() |
f48356cbee | ||
![]() |
3538a1df3d | ||
![]() |
c15fbee537 | ||
![]() |
7612c3ece0 | ||
![]() |
d3d05fa397 | ||
![]() |
1fa7ce5486 | ||
![]() |
bc74ba5b35 | ||
![]() |
caebc583da | ||
![]() |
57e933e68a | ||
![]() |
c104913f81 | ||
![]() |
d38a5659a9 | ||
![]() |
0c54d2c47c | ||
![]() |
4bb52f0357 | ||
![]() |
c1594b2482 | ||
![]() |
41919f9648 | ||
![]() |
79e0fd1343 | ||
![]() |
b1b78feec2 | ||
![]() |
f27538607e | ||
![]() |
2fc70c62a5 | ||
![]() |
a3890c0304 | ||
![]() |
953d7d0428 | ||
![]() |
1a0e2abb78 | ||
![]() |
5b0c7694d3 | ||
![]() |
9e0b0778f8 | ||
![]() |
120fff31a7 | ||
![]() |
4d4d54d030 | ||
![]() |
2c9bfaa49c | ||
![]() |
f39ddbc00d | ||
![]() |
8094dd4075 | ||
![]() |
52d94231c7 | ||
![]() |
ac8e647b92 | ||
![]() |
da1fb935b4 | ||
![]() |
83188e7ea4 | ||
![]() |
3a69273f0c | ||
![]() |
511542eaf8 | ||
![]() |
976863518b | ||
![]() |
895afcdb0e | ||
![]() |
da2636d6f7 | ||
![]() |
27d3be0356 | ||
![]() |
fa196f85a7 | ||
![]() |
9a3a64a9bd | ||
![]() |
5c3ac75c31 | ||
![]() |
1a383c47b5 | ||
![]() |
00261cb90c | ||
![]() |
b10c2d56a1 | ||
![]() |
2c1b3aa3d3 | ||
![]() |
fa937612c5 | ||
![]() |
fcd97f5ce0 | ||
![]() |
818c33cc37 | ||
![]() |
f7db472224 | ||
![]() |
261e7efdee | ||
![]() |
1ba783af68 | ||
![]() |
83ddb89ff7 | ||
![]() |
b82e4860cd | ||
![]() |
668af619fe | ||
![]() |
4f0802b2b2 | ||
![]() |
69c83ab391 | ||
![]() |
2ec7ca143f | ||
![]() |
f451686f1d | ||
![]() |
030bb019b0 | ||
![]() |
9fa2b002ba | ||
![]() |
f98795abfd | ||
![]() |
92f7b54371 | ||
![]() |
4d6a139bf8 | ||
![]() |
08c087f221 | ||
![]() |
2c9cd760a9 | ||
![]() |
45e91b3664 | ||
![]() |
d0de6f8326 | ||
![]() |
377b78af11 | ||
![]() |
96d89eb50c | ||
![]() |
2d99bba427 | ||
![]() |
a9f139e062 | ||
![]() |
c91c6970de | ||
![]() |
e57dde7bb0 | ||
![]() |
9291543705 | ||
![]() |
1e079027ec | ||
![]() |
d6afd5c198 | ||
![]() |
4b4053d174 | ||
![]() |
77ac3b6da0 | ||
![]() |
42e0c72dd9 | ||
![]() |
190c7a6559 | ||
![]() |
af7af0aa85 | ||
![]() |
f734777cfe | ||
![]() |
93721b7f10 | ||
![]() |
236406e1ee | ||
![]() |
bd55823d10 | ||
![]() |
1ed532589e | ||
![]() |
cbd7a6b138 | ||
![]() |
befbe01963 | ||
![]() |
d891f9ea02 | ||
![]() |
b8d114e229 | ||
![]() |
27457efc30 | ||
![]() |
387093dceb | ||
![]() |
ee60b161fd | ||
![]() |
03456f610c | ||
![]() |
08b30a2bc4 | ||
![]() |
1a14439186 | ||
![]() |
b73e7de8e9 | ||
![]() |
2ffc114f50 | ||
![]() |
37f174b43a | ||
![]() |
d62790cd78 | ||
![]() |
77589c18f4 | ||
![]() |
aef715e8bb | ||
![]() |
2610cfcfde | ||
![]() |
eb4433162c | ||
![]() |
d11f46bbce | ||
![]() |
aa7899e9dc | ||
![]() |
4c749e3004 | ||
![]() |
212784b68e | ||
![]() |
b061d083ba | ||
![]() |
44d44f87ac | ||
![]() |
cee5d6e5ee | ||
![]() |
78c1694451 | ||
![]() |
f9b2db4405 | ||
![]() |
b6e0e5698a | ||
![]() |
6a62467998 | ||
![]() |
645c84bc1a | ||
![]() |
05f02fb956 | ||
![]() |
381225059e | ||
![]() |
6936d33172 | ||
![]() |
6857cc2b97 | ||
![]() |
d5f9153c94 | ||
![]() |
a91a2ce4ca | ||
![]() |
592141daaa | ||
![]() |
6e79ec1624 | ||
![]() |
43a9641ae8 | ||
![]() |
484ea10037 | ||
![]() |
9a786a50d6 | ||
![]() |
38ffe21b69 | ||
![]() |
80a13e43e9 | ||
![]() |
c8e22a3653 | ||
![]() |
89b54f19c8 | ||
![]() |
e8883a2a2e | ||
![]() |
1cdc9b6097 | ||
![]() |
68382d89b4 | ||
![]() |
14a32a6472 | ||
![]() |
19aaa64fe9 | ||
![]() |
8270967cdc | ||
![]() |
1abd3c68ec | ||
![]() |
37618b0f57 | ||
![]() |
84c1ad59a2 | ||
![]() |
1315a28252 | ||
![]() |
4d92531288 | ||
![]() |
225ba90b80 | ||
![]() |
0dc9339b1e | ||
![]() |
e2ab919ba2 | ||
![]() |
68947d318e | ||
![]() |
edcf5f8a03 | ||
![]() |
513048603f | ||
![]() |
5a5cab1b8d | ||
![]() |
4d41685ae9 | ||
![]() |
61fc15ee48 | ||
![]() |
46b63bb594 | ||
![]() |
e7f6e069f6 | ||
![]() |
8744da3bf8 | ||
![]() |
6a487a5dc7 | ||
![]() |
28e2f57c76 | ||
![]() |
ee4767b1ce | ||
![]() |
9e666ddf40 | ||
![]() |
760ed25f0c | ||
![]() |
8803fd7fff | ||
![]() |
15fe79178b | ||
![]() |
721f33c857 | ||
![]() |
d10a35efea | ||
![]() |
6162b7abca | ||
![]() |
4c608f132b | ||
![]() |
5b67f8c932 | ||
![]() |
afd64625fb | ||
![]() |
cfe8c5bc32 | ||
![]() |
9bcdb4f0be | ||
![]() |
14ae91c047 | ||
![]() |
8b68940953 | ||
![]() |
3791c9594d | ||
![]() |
c38ffe9baf | ||
![]() |
a1d517d6c0 | ||
![]() |
3d9159a4cb | ||
![]() |
0c66a98f3e | ||
![]() |
3388d80024 | ||
![]() |
ce950a80b2 | ||
![]() |
4c7c8a6262 | ||
![]() |
3973d812fd | ||
![]() |
480f2a5681 | ||
![]() |
73a475d13a | ||
![]() |
34e34b8b15 | ||
![]() |
bd0ee86db9 | ||
![]() |
4feba8bcf3 | ||
![]() |
da62c41e87 | ||
![]() |
e09f0a6b11 | ||
![]() |
ea98785097 | ||
![]() |
4abf945b71 | ||
![]() |
622bda9f66 | ||
![]() |
93712b37d3 | ||
![]() |
6cb5cfb0c9 | ||
![]() |
e9787c5a88 | ||
![]() |
664889d487 | ||
![]() |
03f4318e40 | ||
![]() |
78c461750e | ||
![]() |
b1e82e6187 | ||
![]() |
dcbb3fee7c | ||
![]() |
fbed1a20b0 | ||
![]() |
92ac06e55d | ||
![]() |
6d0efa638f | ||
![]() |
d8bc10c583 | ||
![]() |
5569482830 | ||
![]() |
ab97be2269 | ||
![]() |
847e34bfdb | ||
![]() |
139b641803 | ||
![]() |
ac77486b07 | ||
![]() |
757fedfc44 | ||
![]() |
1717805dea | ||
![]() |
b17a1ea07a | ||
![]() |
7cfa818e63 | ||
![]() |
30ac868757 | ||
![]() |
64db518837 | ||
![]() |
d8cde59aaf | ||
![]() |
049c5cfa9d | ||
![]() |
3d2bfa34c8 | ||
![]() |
5d63c58f2c | ||
![]() |
cab701f054 | ||
![]() |
0764fea159 | ||
![]() |
269cadff15 | ||
![]() |
f618f25d7e | ||
![]() |
921908fe33 | ||
![]() |
cb27bdb2f7 | ||
![]() |
f2840468b4 | ||
![]() |
f978ef2cda | ||
![]() |
676180afca | ||
![]() |
a29d4382e1 | ||
![]() |
7d7d99cb70 | ||
![]() |
ceab90233c | ||
![]() |
348e728220 | ||
![]() |
7bfcf2040d | ||
![]() |
e60df795ad | ||
![]() |
1ef79ce5f1 | ||
![]() |
7917ec611a | ||
![]() |
e94b24ec39 | ||
![]() |
19fc63e3af | ||
![]() |
b8b58e980b | ||
![]() |
6475e042b5 | ||
![]() |
f0b15e1f04 | ||
![]() |
907283b9a4 | ||
![]() |
a6c8bcd878 | ||
![]() |
b83e214df5 | ||
![]() |
207d1d2806 | ||
![]() |
1dd5007fa8 | ||
![]() |
7f3f62e46d | ||
![]() |
2920127ada | ||
![]() |
2c1ded37a1 | ||
![]() |
17912b4695 | ||
![]() |
bda7fcc784 | ||
![]() |
37c3ac5413 | ||
![]() |
4aa493b96c | ||
![]() |
c1b06d63b6 | ||
![]() |
9e8b85a957 | ||
![]() |
b14abffea3 | ||
![]() |
37e0b9b904 | ||
![]() |
3f1b4438e4 | ||
![]() |
e1a4053426 | ||
![]() |
23c3323871 | ||
![]() |
67dd50a7f7 | ||
![]() |
ccf20f456a | ||
![]() |
8978d1ff74 | ||
![]() |
6ec7d96ec9 | ||
![]() |
a35146ab61 | ||
![]() |
1233bc3a42 | ||
![]() |
36446ceded | ||
![]() |
0947bffeef | ||
![]() |
ff34739f40 | ||
![]() |
a37f804469 | ||
![]() |
53c8aa25cb | ||
![]() |
e3f34d6f11 | ||
![]() |
e6936c177b | ||
![]() |
e3d4b84803 | ||
![]() |
395fc33ccc | ||
![]() |
4edf0d8cd3 | ||
![]() |
4ccf61a6d7 | ||
![]() |
b30de96525 | ||
![]() |
6f707e8722 | ||
![]() |
bfee030d7b | ||
![]() |
b18d1fb970 | ||
![]() |
2c3ea5b74e | ||
![]() |
e80caabee6 | ||
![]() |
9080305070 | ||
![]() |
983dd87ffb | ||
![]() |
7e8b3c389d | ||
![]() |
6ded9a1bc6 | ||
![]() |
5c20cf4563 | ||
![]() |
eabc316c7b | ||
![]() |
05d39f79b0 | ||
![]() |
c239721021 | ||
![]() |
a8fa77c6b9 | ||
![]() |
f8b0329b37 | ||
![]() |
1e45f63a7c | ||
![]() |
1f98162377 | ||
![]() |
678ae87c62 | ||
![]() |
e129fa6819 | ||
![]() |
18af06237c | ||
![]() |
fa4643fddf | ||
![]() |
b7fcd41737 | ||
![]() |
e36fe79782 | ||
![]() |
644faaf65b | ||
![]() |
17e14cefd9 | ||
![]() |
d32949017b | ||
![]() |
48e4c44b32 | ||
![]() |
4e83237d47 | ||
![]() |
08cf0def6e | ||
![]() |
060659044e | ||
![]() |
e396043f79 | ||
![]() |
0308a88111 | ||
![]() |
be56305b4e | ||
![]() |
d4d5c4aac8 | ||
![]() |
d84fd324b2 | ||
![]() |
6cb385f6a7 | ||
![]() |
e7c6b2d571 | ||
![]() |
1787f6130d | ||
![]() |
a7704a369d | ||
![]() |
ca5c714037 | ||
![]() |
f4284023fd | ||
![]() |
512a1dfad6 | ||
![]() |
ce43b7b3d9 | ||
![]() |
e33fa96599 | ||
![]() |
7f966df5a4 | ||
![]() |
dda7be99eb | ||
![]() |
ac9e24e2ed | ||
![]() |
e340c9aaba | ||
![]() |
125c266585 | ||
![]() |
5514fc11b9 | ||
![]() |
9f7ba51f39 | ||
![]() |
dcaaae9a4c | ||
![]() |
cf16eda76e | ||
![]() |
bf22d89f67 | ||
![]() |
ff8e145b90 | ||
![]() |
fad62b996a | ||
![]() |
61aef0bff0 | ||
![]() |
95e141ed15 | ||
![]() |
8f4e86e476 | ||
![]() |
03da70cb81 | ||
![]() |
6e3ae0afc2 | ||
![]() |
c724892158 | ||
![]() |
d34533981f | ||
![]() |
db541abed4 | ||
![]() |
d87268acfe | ||
![]() |
19342c8768 | ||
![]() |
5d524e8060 | ||
![]() |
a995872d1c | ||
![]() |
d2368f5cbb | ||
![]() |
2313b8ea05 | ||
![]() |
fe078666c6 | ||
![]() |
fbd22c8124 | ||
![]() |
759d963a04 | ||
![]() |
8a17e2bfbf | ||
![]() |
bf311e6467 | ||
![]() |
4f6d70ded0 | ||
![]() |
8d05e7c5b9 | ||
![]() |
c93b82d6e1 | ||
![]() |
b8f2d8fb0c | ||
![]() |
124cc4c9cc | ||
![]() |
b7333557a1 | ||
![]() |
6360802612 | ||
![]() |
9e70bddc9d | ||
![]() |
f305ff3a5a | ||
![]() |
4806d30406 | ||
![]() |
b3d5cd9e4b | ||
![]() |
c6bed1e108 | ||
![]() |
7411a8bafa | ||
![]() |
300f85720c | ||
![]() |
c9382f8969 | ||
![]() |
c43092da9a | ||
![]() |
bea6cf29c2 | ||
![]() |
0cc5d66e5b | ||
![]() |
7d44970f78 | ||
![]() |
2be5225440 | ||
![]() |
cb25bd4a88 | ||
![]() |
b72afb6895 | ||
![]() |
1c6700c688 | ||
![]() |
9f9117c318 | ||
![]() |
1e0295fad5 | ||
![]() |
95b5854449 | ||
![]() |
cf3c0b2eb5 | ||
![]() |
74ca009b0b | ||
![]() |
6f9d9cd5a8 | ||
![]() |
09705fd1b4 | ||
![]() |
d831fab381 | ||
![]() |
0e3e2e5ccc | ||
![]() |
f81bab8895 | ||
![]() |
e3ed1ab8ec | ||
![]() |
433da8ffce | ||
![]() |
30acd26898 | ||
![]() |
66d5f4f3b8 | ||
![]() |
73c2c34127 | ||
![]() |
ad0e89e147 | ||
![]() |
73f8c97d1d | ||
![]() |
389c707ad2 | ||
![]() |
c23653338f | ||
![]() |
76c35307b2 | ||
![]() |
92422d853d | ||
![]() |
5210d8c0a2 | ||
![]() |
56079d080d | ||
![]() |
2946c935ee | ||
![]() |
180b0af3c9 | ||
![]() |
f3765bc391 | ||
![]() |
531042467a | ||
![]() |
71e6e04d77 | ||
![]() |
0128ec2ba6 | ||
![]() |
b8f4cb5435 | ||
![]() |
4e03efaba9 | ||
![]() |
f56668e467 | ||
![]() |
458134de5d | ||
![]() |
06d6e21de8 | ||
![]() |
8d2f461350 | ||
![]() |
db4152c4ca | ||
![]() |
b01b1faa3f | ||
![]() |
f221a7ae74 | ||
![]() |
2b7b5e3f08 | ||
![]() |
4f855f82ea | ||
![]() |
d0e9bcbfdc | ||
![]() |
447f26e1b9 | ||
![]() |
7eb3c87fa0 | ||
![]() |
7ce1b354cc | ||
![]() |
efbc1f836b | ||
![]() |
7c33f9c579 | ||
![]() |
a9255bddb5 | ||
![]() |
0de928703f | ||
![]() |
1d8f1bd7ae | ||
![]() |
9414e001f3 | ||
![]() |
6d80a19518 | ||
![]() |
04a718dda8 | ||
![]() |
202b9d1c79 | ||
![]() |
011a2dbfaf | ||
![]() |
22cbf74dc8 | ||
![]() |
71f1ea86d2 | ||
![]() |
844ee089d8 | ||
![]() |
9a54c8ca49 | ||
![]() |
b3c1b21f80 | ||
![]() |
60b34bcfca | ||
![]() |
e773d63c16 | ||
![]() |
6e8e88692c | ||
![]() |
391ac70e60 | ||
![]() |
c736b1dae5 | ||
![]() |
649e5cfda5 | ||
![]() |
c7db0f479d | ||
![]() |
94a9dcede8 | ||
![]() |
0083d09a8b | ||
![]() |
b34fb8bf7c | ||
![]() |
0f481546cd | ||
![]() |
c240512ef4 | ||
![]() |
2b3ab02ebf | ||
![]() |
7abf28bcbc | ||
![]() |
2277a88f4d | ||
![]() |
ab797c95af | ||
![]() |
c819961cc8 | ||
![]() |
81b873dead | ||
![]() |
b6db97d313 | ||
![]() |
f49a8009ec | ||
![]() |
5bd412071a | ||
![]() |
1d3de77f63 | ||
![]() |
4f88a5f2ad | ||
![]() |
11b1dbf0ff | ||
![]() |
b961235187 | ||
![]() |
124d92daa9 | ||
![]() |
3f07d2d37c | ||
![]() |
1e709f5b3f | ||
![]() |
7b7387a68c | ||
![]() |
2020cdffd5 | ||
![]() |
349abc8d1b | ||
![]() |
cc99330063 | ||
![]() |
92553fa666 | ||
![]() |
5264a18dfa | ||
![]() |
7e6a241e03 | ||
![]() |
6bb1a5dfd2 | ||
![]() |
7b3556e4ad | ||
![]() |
9a07505075 | ||
![]() |
0b65137831 | ||
![]() |
761c5109dc | ||
![]() |
729f5c0833 | ||
![]() |
f7199f205f | ||
![]() |
d6b5dc93cc | ||
![]() |
11baf237bc | ||
![]() |
2d281855fc | ||
![]() |
73fee6372b | ||
![]() |
2458f667c4 | ||
![]() |
f3e2cf0a58 | ||
![]() |
0f0b2687af | ||
![]() |
a3ede3cf8a | ||
![]() |
b594f198a9 | ||
![]() |
4ef6214029 | ||
![]() |
82f8694464 | ||
![]() |
c54259ecc6 | ||
![]() |
7e48b3514c | ||
![]() |
f0270c6e34 | ||
![]() |
ac3dfbc30d | ||
![]() |
9a0211a71c | ||
![]() |
198d067e25 | ||
![]() |
72209986b6 | ||
![]() |
dd7820e4ee | ||
![]() |
2a28964e63 | ||
![]() |
e207b2f50b | ||
![]() |
d5b60237a2 | ||
![]() |
bc96db8612 | ||
![]() |
81bd956ae8 | ||
![]() |
c8cec63cb9 | ||
![]() |
83beacf84a | ||
![]() |
cc2dbdcb44 | ||
![]() |
1f89844c67 | ||
![]() |
81a56549da | ||
![]() |
22cc698b4e | ||
![]() |
c58d2add37 | ||
![]() |
5a5a54fc66 | ||
![]() |
a42ad7ead9 | ||
![]() |
6536368467 | ||
![]() |
973d3aed9a | ||
![]() |
fa300742ea | ||
![]() |
15472274ee | ||
![]() |
f3485bfc13 | ||
![]() |
060ad34e1d | ||
![]() |
ebf4403eca | ||
![]() |
fb316874ef | ||
![]() |
9236898a9d | ||
![]() |
1c3527f5c4 | ||
![]() |
6f4002a56f | ||
![]() |
3f99ff65ed | ||
![]() |
c7c8575c9b | ||
![]() |
63dbcd79e2 | ||
![]() |
9dc85d4a76 | ||
![]() |
88686c44fe | ||
![]() |
3f1d85e189 | ||
![]() |
283f1b19a7 | ||
![]() |
ab8f9e5412 | ||
![]() |
4f85b18b08 | ||
![]() |
a6ae208fe7 | ||
![]() |
0c13227f7d | ||
![]() |
1edbd2d498 | ||
![]() |
4c7d4e6c0a | ||
![]() |
458ca4a983 | ||
![]() |
6a83f40135 | ||
![]() |
281407247b | ||
![]() |
172e7d494f | ||
![]() |
8763390dfe | ||
![]() |
c26144da75 | ||
![]() |
d025495374 | ||
![]() |
f58fc4c367 | ||
![]() |
cc6a740a0f | ||
![]() |
909444dacf | ||
![]() |
c28a0ed9a3 | ||
![]() |
cd0d37ce07 | ||
![]() |
d0ad840ef4 | ||
![]() |
edab4efa42 | ||
![]() |
877b7b2910 | ||
![]() |
66675cf977 | ||
![]() |
0e4ff91d6b | ||
![]() |
dd7b1be7f4 | ||
![]() |
102a7695a3 | ||
![]() |
755c9eea1c | ||
![]() |
e5fcc50ae2 | ||
![]() |
8bb037f82e | ||
![]() |
a0c35101fb | ||
![]() |
af1eaac5ff | ||
![]() |
dbbfc735f0 | ||
![]() |
711575736d | ||
![]() |
c4ce7f9800 | ||
![]() |
594a4e0ba3 | ||
![]() |
c1d5510428 | ||
![]() |
a3d6266d96 | ||
![]() |
aa19ec3ddb | ||
![]() |
0e1139a7a4 | ||
![]() |
dc79af2d98 | ||
![]() |
cc955b1e66 | ||
![]() |
da34ff964f | ||
![]() |
d6a2965cb2 | ||
![]() |
4b429e440b | ||
![]() |
8759b4a0d3 | ||
![]() |
df840b7cd5 | ||
![]() |
0645dc70a5 | ||
![]() |
b230b35c62 | ||
![]() |
31da9351f0 | ||
![]() |
93d39370b6 | ||
![]() |
cea210d800 | ||
![]() |
7b65bcf13c | ||
![]() |
335b7564d5 | ||
![]() |
202e9ad9ce | ||
![]() |
9dc4e8f290 | ||
![]() |
99d27c154e | ||
![]() |
5943fc1895 | ||
![]() |
9efc20e58a | ||
![]() |
6d8234fa27 | ||
![]() |
ad76c28a66 | ||
![]() |
131d07e649 | ||
![]() |
776bb79f0b | ||
![]() |
12e62488c6 | ||
![]() |
aedfaa3641 | ||
![]() |
83ac42cbdc | ||
![]() |
a5ce8d0d77 | ||
![]() |
0ee2e404da | ||
![]() |
3947e79086 | ||
![]() |
91ab1071d2 | ||
![]() |
409e911752 | ||
![]() |
9983bd8d92 | ||
![]() |
32c71c4108 | ||
![]() |
ef6952e3ea | ||
![]() |
173b7aa308 | ||
![]() |
c4727f19e1 | ||
![]() |
b8a74793ca | ||
![]() |
c1dede9369 | ||
![]() |
0c4ea504d8 | ||
![]() |
b265b6b190 | ||
![]() |
d57a61b50f | ||
![]() |
4fc9106c17 | ||
![]() |
38e098ca31 | ||
![]() |
e7ad38d827 | ||
![]() |
b5e5127d48 | ||
![]() |
a1ce9aacf2 | ||
![]() |
322b847356 | ||
![]() |
98338e4c7f | ||
![]() |
171a89f37b | ||
![]() |
8114b541a8 | ||
![]() |
c48396c5c6 | ||
![]() |
00371546a3 | ||
![]() |
87e7b62c85 | ||
![]() |
15ffe5c254 | ||
![]() |
a767dad3a1 | ||
![]() |
9387246f83 | ||
![]() |
bed20de302 | ||
![]() |
70fc5393b1 | ||
![]() |
9b80dbe014 | ||
![]() |
78a013d63a | ||
![]() |
24f4aa79c8 | ||
![]() |
dfc94b5ad6 | ||
![]() |
ddfe8f3921 | ||
![]() |
4af752028f | ||
![]() |
b149828c9f | ||
![]() |
3dc26e78ef | ||
![]() |
5acbe37e6f | ||
![]() |
d9ef8fa206 | ||
![]() |
292499aebc | ||
![]() |
717493e668 | ||
![]() |
d49f958d4d | ||
![]() |
33ee32865f | ||
![]() |
17f8939f97 | ||
![]() |
1b7fe9523d | ||
![]() |
0763f56047 | ||
![]() |
1ea282fba8 | ||
![]() |
869fa2631e | ||
![]() |
f336a91fee | ||
![]() |
d302b6e198 | ||
![]() |
ed2e1f3f72 | ||
![]() |
b4d82084a9 | ||
![]() |
53b96dfb89 | ||
![]() |
0e3fb6cbdd | ||
![]() |
6b12a45a95 | ||
![]() |
0b9c4c18dd | ||
![]() |
d0cc8cb64b | ||
![]() |
bb86e71e65 | ||
![]() |
8aa6297308 | ||
![]() |
d3b631a952 | ||
![]() |
47d495fc01 | ||
![]() |
32322b23b2 | ||
![]() |
c0ba98e26f | ||
![]() |
a5a7cd3107 | ||
![]() |
a729408599 | ||
![]() |
4dddc53735 | ||
![]() |
5f42caad03 | ||
![]() |
5475672a9d | ||
![]() |
833cdcb6d2 | ||
![]() |
c95bc9fe44 | ||
![]() |
a1fa9decad | ||
![]() |
4a5fe4138e | ||
![]() |
002fdeae67 | ||
![]() |
5802a66469 | ||
![]() |
71e8f75a01 | ||
![]() |
ee816b2251 | ||
![]() |
f094c59cd0 | ||
![]() |
d25ffdb292 | ||
![]() |
2461d01329 | ||
![]() |
2207a91f7b | ||
![]() |
5cafca1be0 | ||
![]() |
33957e5360 | ||
![]() |
ff92b13f35 | ||
![]() |
9c5a04f25f | ||
![]() |
e76f4e9bd9 | ||
![]() |
0df091f387 | ||
![]() |
66277fbb6c | ||
![]() |
a67ff3843a | ||
![]() |
9ae839ad72 | ||
![]() |
66f71aecf7 | ||
![]() |
0b203a3673 | ||
![]() |
26c3f9f914 | ||
![]() |
474c248c9d | ||
![]() |
5b1b6b5be0 | ||
![]() |
45e9030358 | ||
![]() |
f9c1600f0d | ||
![]() |
ad85f8882b | ||
![]() |
206ed06905 | ||
![]() |
e407ba47c2 | ||
![]() |
7fdf42a56f | ||
![]() |
4eea541352 | ||
![]() |
1ffdd32013 | ||
![]() |
99506845f7 | ||
![]() |
ed9c67804a | ||
![]() |
9c20cd5f7b | ||
![]() |
6c86827d3a | ||
![]() |
d2b2f3d54d | ||
![]() |
64b3397f8e | ||
![]() |
0829517b72 | ||
![]() |
c1bfc1df67 | ||
![]() |
96c0c43dc8 | ||
![]() |
a68c7f4ef8 | ||
![]() |
7c474e6827 | ||
![]() |
143bab87f1 | ||
![]() |
580f35112e | ||
![]() |
3249ffb273 | ||
![]() |
7bae9463b2 | ||
![]() |
ae30ac6e3c | ||
![]() |
46ed520886 | ||
![]() |
ace02a6dfa | ||
![]() |
0d59754be2 | ||
![]() |
15bd26c9b1 | ||
![]() |
bc371acb3e | ||
![]() |
2eb5fbf112 | ||
![]() |
ffd05f90f3 | ||
![]() |
fc0fb158d5 | ||
![]() |
404807c697 | ||
![]() |
29ea7c53f2 | ||
![]() |
1fc4af9c86 | ||
![]() |
ac762762c3 | ||
![]() |
553676aade | ||
![]() |
a13b9815f6 | ||
![]() |
156e7cc628 | ||
![]() |
959ca0f412 | ||
![]() |
9755fa0537 | ||
![]() |
77ec86d31a | ||
![]() |
189d4b459f | ||
![]() |
44f40966e7 | ||
![]() |
3a8c290f91 | ||
![]() |
7d3313e732 | ||
![]() |
591b50dfa7 | ||
![]() |
27ef661fec | ||
![]() |
d7935abc14 | ||
![]() |
11068aa9d0 | ||
![]() |
1234003527 | ||
![]() |
e5ebf938f6 | ||
![]() |
8c2c07fd18 | ||
![]() |
9e1a50c3be | ||
![]() |
ac8ddada0b | ||
![]() |
885485da70 | ||
![]() |
bb4e863e87 | ||
![]() |
c7a4220d65 | ||
![]() |
03dd9b2d42 | ||
![]() |
89ca085b94 | ||
![]() |
fffd9defea | ||
![]() |
d10fea6012 | ||
![]() |
ab26aee8b2 | ||
![]() |
bb80a7b2ee | ||
![]() |
e4a6b29279 | ||
![]() |
d12c7809dd | ||
![]() |
357ce0382e | ||
![]() |
73da3d9b20 | ||
![]() |
e67b7a6d5e | ||
![]() |
4e25bebdd0 | ||
![]() |
abd22d2566 | ||
![]() |
8aeb597780 | ||
![]() |
33825f6d96 | ||
![]() |
eca504cb07 | ||
![]() |
4c75440af4 | ||
![]() |
94f7528885 | ||
![]() |
4dadf6d353 | ||
![]() |
2d27e72ed9 | ||
![]() |
4ff0c8a8d1 | ||
![]() |
f9fba94863 | ||
![]() |
f9b246dbd0 | ||
![]() |
8fefded8dc | ||
![]() |
18824830fd | ||
![]() |
fa81d87dc0 | ||
![]() |
8bc145472a | ||
![]() |
7afc1e9762 | ||
![]() |
fc59c83e16 | ||
![]() |
e4048be088 | ||
![]() |
d715a8c290 | ||
![]() |
ad308252a1 | ||
![]() |
c7d9f83638 | ||
![]() |
828fdbfd2d | ||
![]() |
40c6fda19d | ||
![]() |
b69816c2f9 | ||
![]() |
46f5234bd9 | ||
![]() |
81b8d7a66b | ||
![]() |
b1285a16c1 | ||
![]() |
90140e7710 | ||
![]() |
8364e68667 | ||
![]() |
4bb420d049 | ||
![]() |
560dc68120 | ||
![]() |
8fcb8e54f7 | ||
![]() |
6c70e56059 | ||
![]() |
b24d292ade | ||
![]() |
2137de37b9 | ||
![]() |
3c591ad8a9 | ||
![]() |
b56f4c4558 | ||
![]() |
5d8bcb42c6 | ||
![]() |
b299652e86 | ||
![]() |
8ac4b001a2 | ||
![]() |
6294ce7807 | ||
![]() |
8173cd7776 | ||
![]() |
edaccd86d6 | ||
![]() |
5f77408956 | ||
![]() |
e836523bc3 | ||
![]() |
9f866be110 | ||
![]() |
f6879f40b0 | ||
![]() |
06f47f262f | ||
![]() |
eda52a3b82 | ||
![]() |
3f1ab66899 | ||
![]() |
af844ea9d5 | ||
![]() |
b75efcbca2 | ||
![]() |
25043278ab | ||
![]() |
644069fb23 | ||
![]() |
0eccb6a610 | ||
![]() |
0abd514064 | ||
![]() |
3879fde06d | ||
![]() |
887433fc6a | ||
![]() |
dd7a07bd0d | ||
![]() |
0ee32cf110 | ||
![]() |
72aa68cedc | ||
![]() |
9adffa1ef5 | ||
![]() |
4ca267ea17 | ||
![]() |
833768172d | ||
![]() |
1ec459ea3a | ||
![]() |
66d0ad5803 | ||
![]() |
92ac025e43 | ||
![]() |
e8b2fde753 | ||
![]() |
0fc7999780 | ||
![]() |
3a403392e7 | ||
![]() |
acccc6fd93 | ||
![]() |
40bb4765d4 | ||
![]() |
48c60621b6 | ||
![]() |
51509760e3 | ||
![]() |
1e1610671e | ||
![]() |
de86c37687 | ||
![]() |
6e332bbdf8 | ||
![]() |
8a8a0c7dec | ||
![]() |
d4b9b5a7dd | ||
![]() |
6df541e1fd | ||
![]() |
748087483c | ||
![]() |
ae91fa6a39 | ||
![]() |
2897afce41 | ||
![]() |
ee8091ba91 | ||
![]() |
30b5faebae | ||
![]() |
8d753f821d | ||
![]() |
54eb03d2a1 | ||
![]() |
dd6276e706 | ||
![]() |
f67ec241d4 | ||
![]() |
8ade85edec | ||
![]() |
a2ca18a714 | ||
![]() |
6a83ff2511 | ||
![]() |
bc3a06178b | ||
![]() |
9fda259c0c | ||
![]() |
d4925622f9 | ||
![]() |
dbeaf43b8f | ||
![]() |
f86957e5e1 | ||
![]() |
a2f42d51fd | ||
![]() |
0b71cfaf06 | ||
![]() |
d558ac83b6 | ||
![]() |
74efc94649 | ||
![]() |
2541a345d0 | ||
![]() |
23ce1e930d | ||
![]() |
6ebad84160 | ||
![]() |
24ac9f3e5a | ||
![]() |
2a15b95f18 | ||
![]() |
757150dec1 | ||
![]() |
ddcec82b61 | ||
![]() |
74047453ef | ||
![]() |
dcaed0e90f | ||
![]() |
cae304e07f | ||
![]() |
039ab1ccd7 | ||
![]() |
47ad0ca993 | ||
![]() |
9c751230a1 | ||
![]() |
a468ed316d | ||
![]() |
e725730982 | ||
![]() |
21c12d118b | ||
![]() |
b9e74ee9ab | ||
![]() |
0f2cff5078 | ||
![]() |
e5e196bd7f | ||
![]() |
077402406b | ||
![]() |
54900ae318 | ||
![]() |
3c015bf822 | ||
![]() |
a1efcfb2d0 | ||
![]() |
75d531285a | ||
![]() |
0aad7db2d2 | ||
![]() |
20c3b890ae | ||
![]() |
0126960d79 | ||
![]() |
849d441c5c | ||
![]() |
b5f5627ca6 | ||
![]() |
5b0c1e5b9e | ||
![]() |
3cff0df0ce | ||
![]() |
15fa55c223 | ||
![]() |
594ca3a04b | ||
![]() |
fafe5623d1 | ||
![]() |
141cf39368 | ||
![]() |
1fa050fd7a | ||
![]() |
f36e7430ae | ||
![]() |
94fd75e014 | ||
![]() |
95d6da3111 | ||
![]() |
4dc4704bb4 | ||
![]() |
18bf7f93fa | ||
![]() |
c73f694c63 | ||
![]() |
3688a3bc67 | ||
![]() |
775a3a1c22 | ||
![]() |
bbbb3b4a06 | ||
![]() |
576191cd4e | ||
![]() |
38d398c967 | ||
![]() |
7da44115d3 | ||
![]() |
b54032bdc7 | ||
![]() |
cab497e81e | ||
![]() |
50e9c67609 | ||
![]() |
bd57ea0110 | ||
![]() |
05fe7f8a48 | ||
![]() |
c0bd3b362c | ||
![]() |
6381028fd6 | ||
![]() |
1f328be1bd | ||
![]() |
ddfdb71783 | ||
![]() |
da1478c0c1 | ||
![]() |
40fe3b4358 | ||
![]() |
20fd1db0f4 | ||
![]() |
a65aaab849 | ||
![]() |
a5595189ed | ||
![]() |
4a1da3ebc5 | ||
![]() |
35a4460334 | ||
![]() |
a6ccb37683 | ||
![]() |
68465aed49 | ||
![]() |
fc3aac96f2 | ||
![]() |
32c7669b28 | ||
![]() |
fef30bc671 | ||
![]() |
ae547d27e4 | ||
![]() |
be3e1831d4 | ||
![]() |
45aceea53b | ||
![]() |
25819584bd | ||
![]() |
4c24b70d47 | ||
![]() |
4c12673fbb | ||
![]() |
e935db5075 | ||
![]() |
a7f1f8d327 | ||
![]() |
8c540d7210 | ||
![]() |
4c4b884f8e | ||
![]() |
a3d3fe07ce | ||
![]() |
1ae521f560 | ||
![]() |
7854e1c2c1 | ||
![]() |
a9ff795948 | ||
![]() |
a8e2f97260 | ||
![]() |
d17253b023 | ||
![]() |
ecbf0410eb | ||
![]() |
cffc431bf0 | ||
![]() |
dc54981784 | ||
![]() |
a7ed90f042 | ||
![]() |
08941ab39a | ||
![]() |
b81a8d26e4 | ||
![]() |
af84af7b7a | ||
![]() |
0f813962be | ||
![]() |
fe57f7f489 | ||
![]() |
12e2c04486 | ||
![]() |
6bafb68d77 | ||
![]() |
e8763b3697 | ||
![]() |
6f2924006c | ||
![]() |
062c305cd8 | ||
![]() |
61a4a4bc2f | ||
![]() |
176af55e8c | ||
![]() |
1a51ce712c | ||
![]() |
811da2e159 | ||
![]() |
535bf6e4b9 | ||
![]() |
515f06ba6c | ||
![]() |
6c43e5dba9 | ||
![]() |
d498fabe72 | ||
![]() |
27e71eb142 | ||
![]() |
7c63cb5bca | ||
![]() |
ddf3a687a3 | ||
![]() |
4515eb4637 | ||
![]() |
efd1194307 | ||
![]() |
5e0d8fe4c7 | ||
![]() |
e44a9e8921 | ||
![]() |
ff9e1da1de | ||
![]() |
1ed8642010 | ||
![]() |
38ff46e45c | ||
![]() |
2362d0e838 | ||
![]() |
90d7fc6bc5 | ||
![]() |
bcae0cf441 | ||
![]() |
edababa88e | ||
![]() |
350abda21a | ||
![]() |
1c24f0054a | ||
![]() |
f7eaace7ae | ||
![]() |
8573016bef | ||
![]() |
6bf2708c0e | ||
![]() |
36d7eb7caa | ||
![]() |
4fc8d33d31 | ||
![]() |
c4e2f3bc70 | ||
![]() |
2f69f5afe6 | ||
![]() |
9bcb928715 | ||
![]() |
e3edcf057c | ||
![]() |
06ccf7e9e9 | ||
![]() |
e4ea35e626 | ||
![]() |
bd906a7915 | ||
![]() |
329bece28d | ||
![]() |
0c86c77d42 | ||
![]() |
3df33199bc | ||
![]() |
fc145016ea | ||
![]() |
c17524bc3c | ||
![]() |
d5acd11164 | ||
![]() |
2a66923524 | ||
![]() |
088a0fb4a5 | ||
![]() |
4f10f82580 | ||
![]() |
5aee70ac7a | ||
![]() |
5ff476c6f9 | ||
![]() |
7ad30f15d5 | ||
![]() |
641f1244dd | ||
![]() |
a1fd29b34b | ||
![]() |
90c1cc3e3b | ||
![]() |
ba49054cd7 | ||
![]() |
61854f1d6a | ||
![]() |
1f9ba1d625 | ||
![]() |
644ea7be4a | ||
![]() |
87ab4e7c9b | ||
![]() |
d84e3cacca | ||
![]() |
2f38d960d4 | ||
![]() |
b4acf4f341 | ||
![]() |
62657ad05a | ||
![]() |
f3784505e0 | ||
![]() |
863f51363a | ||
![]() |
22ee6bb137 | ||
![]() |
3972642ba0 | ||
![]() |
e016bd6900 | ||
![]() |
d2588d9de4 | ||
![]() |
07d1692f2b | ||
![]() |
8db9824842 | ||
![]() |
c8521554c8 | ||
![]() |
ceb7aa8b36 | ||
![]() |
cae11cbb86 | ||
![]() |
03ff3e639f | ||
![]() |
f5dbcd5465 | ||
![]() |
f143fceceb | ||
![]() |
8be139d4d1 | ||
![]() |
2fc58fea81 | ||
![]() |
17901fcfef | ||
![]() |
e7dfbf76bb | ||
![]() |
d6b16a7747 | ||
![]() |
17fa830851 | ||
![]() |
149339a8d9 | ||
![]() |
94de29187a | ||
![]() |
a82c1f303b | ||
![]() |
764cca5a70 | ||
![]() |
18a6aa1824 | ||
![]() |
5c00ed352c | ||
![]() |
7e9a7ad49c | ||
![]() |
fe2fec81ac | ||
![]() |
055f0dfc22 | ||
![]() |
ddf9163c47 | ||
![]() |
e80322dab7 | ||
![]() |
7626dd239a | ||
![]() |
9afa1354da | ||
![]() |
58a471e466 | ||
![]() |
e66f47bdf6 | ||
![]() |
21a50cc452 | ||
![]() |
5239790835 | ||
![]() |
0acbd3d5e8 | ||
![]() |
e3da5ef2d5 | ||
![]() |
ecaba82c9d | ||
![]() |
921c9de241 | ||
![]() |
6a0b5c3a3f | ||
![]() |
a8dcc87019 | ||
![]() |
4ec136cab0 | ||
![]() |
cf7718132a | ||
![]() |
939a055d46 | ||
![]() |
01fa1777ac | ||
![]() |
a77436eec3 | ||
![]() |
c268a126dc | ||
![]() |
29e86d4eeb | ||
![]() |
9d18061d0f | ||
![]() |
943114c052 | ||
![]() |
2cb81ef116 | ||
![]() |
c16450adc8 | ||
![]() |
347d54f388 | ||
![]() |
3428baa3fa | ||
![]() |
4f8066a35a | ||
![]() |
04fd05bc7d | ||
![]() |
3abf89596a | ||
![]() |
690ee3dc15 | ||
![]() |
331c882af2 | ||
![]() |
b4eb83d892 | ||
![]() |
4a35573210 | ||
![]() |
e7fabce4e0 | ||
![]() |
feb2c9fc62 | ||
![]() |
dd7fd16b69 | ||
![]() |
d93d6262ce | ||
![]() |
9d7e499adb | ||
![]() |
0d7a148897 | ||
![]() |
9e825811f2 | ||
![]() |
36cbffcc5e | ||
![]() |
55e1f865d8 | ||
![]() |
3f996cd62c | ||
![]() |
58a8028485 | ||
![]() |
190ce5ee31 | ||
![]() |
70aab068fd | ||
![]() |
617d279419 | ||
![]() |
4de088d725 | ||
![]() |
f8fd746678 | ||
![]() |
1529ee59fe | ||
![]() |
19c253b429 | ||
![]() |
13bb9dd715 | ||
![]() |
9b4602acb3 | ||
![]() |
e5448110fc | ||
![]() |
4974defe6f | ||
![]() |
65ceadda2b | ||
![]() |
8b2adb55ed | ||
![]() |
58ca44bd15 | ||
![]() |
ef46451b80 | ||
![]() |
758b0f9734 | ||
![]() |
3650000b31 | ||
![]() |
dbd042ca3e | ||
![]() |
6b9082bdd9 | ||
![]() |
f9baa3bf20 | ||
![]() |
a75feb7f8f | ||
![]() |
009900b29b | ||
![]() |
dc04cf82d8 | ||
![]() |
b2c23a367d | ||
![]() |
338b59a32e | ||
![]() |
07ffd76437 | ||
![]() |
3eaf9f4011 | ||
![]() |
9832831c5e | ||
![]() |
d3259c4782 | ||
![]() |
940c12d9d8 | ||
![]() |
8f2cbe261b | ||
![]() |
e86788034d | ||
![]() |
4ecc0e15ce | ||
![]() |
b01ce31903 | ||
![]() |
87b69c373a | ||
![]() |
07b3160dff | ||
![]() |
096e2791f5 | ||
![]() |
9d456ccfcf | ||
![]() |
ad5c3741e9 | ||
![]() |
fe188bd646 | ||
![]() |
f47984818f | ||
![]() |
7b274b6974 | ||
![]() |
b1806b0a7c | ||
![]() |
ff2e46650c | ||
![]() |
69fe6cdc05 | ||
![]() |
b7e0d14b83 | ||
![]() |
7db6ed9ad5 | ||
![]() |
da0f63f095 | ||
![]() |
90221e8c94 | ||
![]() |
37680c317c | ||
![]() |
f4f3cfa911 | ||
![]() |
ca0f6e4c0a | ||
![]() |
70ea6fc9a1 | ||
![]() |
a7ccabd8f1 | ||
![]() |
453a8d794e | ||
![]() |
67e692a7f3 | ||
![]() |
ce79898cae | ||
![]() |
bf90daae2b | ||
![]() |
34382ac38e | ||
![]() |
fdb5d53960 | ||
![]() |
2dc5a7f767 | ||
![]() |
65ca3c8fa3 | ||
![]() |
ff34af2c1f | ||
![]() |
e01b6ee76b | ||
![]() |
b94b08a33c | ||
![]() |
540d66af57 | ||
![]() |
1c7ee5f4e4 | ||
![]() |
a2deeb0d12 | ||
![]() |
22fe261dd6 | ||
![]() |
d96f76c27f | ||
![]() |
1da934e63c | ||
![]() |
38a8d34ba5 | ||
![]() |
8e31244fb3 | ||
![]() |
3a124dbb84 | ||
![]() |
b44354ad29 | ||
![]() |
8c23ede683 | ||
![]() |
3ffbdb35a2 | ||
![]() |
4133e454c4 | ||
![]() |
4dce8ff60a | ||
![]() |
2e724291db | ||
![]() |
0504e9ef79 | ||
![]() |
f6b61c26ae | ||
![]() |
1b876bf8d3 | ||
![]() |
b0d42ea116 | ||
![]() |
05bc3839cc | ||
![]() |
281482927a | ||
![]() |
132a712341 | ||
![]() |
b309287087 | ||
![]() |
13d121f443 | ||
![]() |
e891f2ad6d | ||
![]() |
67ba3dbd8b | ||
![]() |
4afa7bf4e1 | ||
![]() |
77bf710299 | ||
![]() |
9b96211faf | ||
![]() |
99e03576bf | ||
![]() |
78d67484e1 | ||
![]() |
e9e86cc5af | ||
![]() |
9b1fb33ac6 | ||
![]() |
70618e93b7 | ||
![]() |
c84511de16 | ||
![]() |
6d9590b4ec | ||
![]() |
33e04fe61f | ||
![]() |
9f43d10ba7 | ||
![]() |
57503cc318 | ||
![]() |
e563692fa2 | ||
![]() |
9c2974438d | ||
![]() |
54e1bd9eeb | ||
![]() |
8212b66ee0 | ||
![]() |
43d2986208 | ||
![]() |
f8f7b74792 | ||
![]() |
5069072a84 | ||
![]() |
93b81756c6 | ||
![]() |
4a867ddd56 | ||
![]() |
a347cb5a42 | ||
![]() |
8a099b4ae5 | ||
![]() |
80e8930e73 | ||
![]() |
2637541c6c | ||
![]() |
da913d8d31 | ||
![]() |
88d4b694f8 | ||
![]() |
b28cc45510 | ||
![]() |
c0b23ca938 | ||
![]() |
8e7b83d2f1 | ||
![]() |
599dd7eecb | ||
![]() |
84348350fe | ||
![]() |
7d03d99852 | ||
![]() |
7c39b176ac | ||
![]() |
4c2e6f75a2 | ||
![]() |
81139e8f47 | ||
![]() |
cea0596cf5 | ||
![]() |
51a1526146 | ||
![]() |
b4db07d7a5 | ||
![]() |
5c15659a34 | ||
![]() |
1bd3285679 | ||
![]() |
6de426c697 | ||
![]() |
d28ad0f0c8 | ||
![]() |
47aecff567 | ||
![]() |
524f03a650 | ||
![]() |
68e6ffdfef | ||
![]() |
29345c429a | ||
![]() |
2cdd483126 | ||
![]() |
f2c46408c4 | ||
![]() |
e5dc476c1e | ||
![]() |
eb2363b93d | ||
![]() |
7bfebd5b61 | ||
![]() |
6addf4d88b | ||
![]() |
c56e7e7c6c | ||
![]() |
78c15f3020 | ||
![]() |
30f0f73a4e | ||
![]() |
e9da453190 | ||
![]() |
91f62cf8ce | ||
![]() |
58dbbd5d29 | ||
![]() |
5c90f7dce7 | ||
![]() |
b7cf5f4105 | ||
![]() |
c850604931 | ||
![]() |
82d2910039 | ||
![]() |
5066fa369d | ||
![]() |
3afd77cbe0 | ||
![]() |
093201a1cc | ||
![]() |
6102e9e5ea | ||
![]() |
91215a1406 | ||
![]() |
a4eb435f1a | ||
![]() |
843d301950 | ||
![]() |
d08fe170f2 | ||
![]() |
51153af944 | ||
![]() |
e7ec014502 | ||
![]() |
2ebd2dfcc7 | ||
![]() |
aaafd63b94 | ||
![]() |
a361372182 | ||
![]() |
8f51f7b4c4 | ||
![]() |
e416e44998 | ||
![]() |
fe4a737421 | ||
![]() |
4ee8557061 | ||
![]() |
88e1d56799 | ||
![]() |
40be915061 | ||
![]() |
0d7ee7a87a | ||
![]() |
baf209f257 | ||
![]() |
c2824d153e | ||
![]() |
d2f88491b1 | ||
![]() |
aacb8c84e0 | ||
![]() |
f44df9fe61 | ||
![]() |
34812b7439 | ||
![]() |
0ce596ec8f | ||
![]() |
2ea1d34f4f | ||
![]() |
a0741aa7b1 | ||
![]() |
188a7de467 | ||
![]() |
1f4ca32e8c | ||
![]() |
784b701cc5 | ||
![]() |
be9e606ae4 | ||
![]() |
fe9a3c9205 | ||
![]() |
012aa63571 | ||
![]() |
ef7846bb41 | ||
![]() |
6948702891 | ||
![]() |
56b4a551dc | ||
![]() |
93e08688be | ||
![]() |
0ed7e278eb | ||
![]() |
b30fecbd28 | ||
![]() |
f050c7b37d | ||
![]() |
f9e1ad253f | ||
![]() |
f0159bf41e | ||
![]() |
21a777ab45 | ||
![]() |
18b8e19847 | ||
![]() |
53a2a865f1 | ||
![]() |
48a87b16b8 | ||
![]() |
46c3ef8c6b | ||
![]() |
94b1350c9d | ||
![]() |
bfbacee7b5 | ||
![]() |
c3455518c2 | ||
![]() |
00e235867a | ||
![]() |
88046ebd15 | ||
![]() |
abc1ecfb60 | ||
![]() |
9bbb88cdcb | ||
![]() |
c867d90f50 | ||
![]() |
1129a2aba4 | ||
![]() |
3410290b45 | ||
![]() |
b34be991bd | ||
![]() |
73755e9777 | ||
![]() |
c871bebee6 | ||
![]() |
a60ffe06ac | ||
![]() |
9f81ce2876 | ||
![]() |
5c33cdba4e | ||
![]() |
e9cdef9f25 | ||
![]() |
d01457e64d | ||
![]() |
c72d304515 | ||
![]() |
10c1f7ead4 | ||
![]() |
7b57a66d45 | ||
![]() |
767033e4d8 | ||
![]() |
e6790d9a6a | ||
![]() |
4bca405e29 | ||
![]() |
bdda89b5e2 | ||
![]() |
2cbc336bc0 | ||
![]() |
6c107883b5 | ||
![]() |
4635e64b2e | ||
![]() |
5b60785cca | ||
![]() |
ef304e6f7f | ||
![]() |
24770148a7 | ||
![]() |
ba6fc0fdb3 | ||
![]() |
89a478ce0a | ||
![]() |
f1bb797fe0 | ||
![]() |
e208241eea | ||
![]() |
02af1b0ac7 | ||
![]() |
3c12872a56 | ||
![]() |
4e5a6eb1c8 | ||
![]() |
5617fbbcb1 | ||
![]() |
15e2df1e5c | ||
![]() |
0d862d6aa8 | ||
![]() |
9ceffeb191 | ||
![]() |
b49cda274d | ||
![]() |
2934c7817d | ||
![]() |
4078a147ef | ||
![]() |
1cb5dcb7dc | ||
![]() |
7aec8222fc | ||
![]() |
30e1969fad | ||
![]() |
a7da468b97 | ||
![]() |
1a0d9e10d7 | ||
![]() |
9514a3d089 | ||
![]() |
349b27b764 | ||
![]() |
e56ce993df | ||
![]() |
3e1861e2ce | ||
![]() |
187d98a153 | ||
![]() |
2d4d1584fd | ||
![]() |
c75fc40833 | ||
![]() |
e3c8901549 | ||
![]() |
6978140492 | ||
![]() |
272a21ffab | ||
![]() |
a8e901b63c | ||
![]() |
bb359f67a4 | ||
![]() |
c9d253a320 | ||
![]() |
b3eab17f2c | ||
![]() |
962d213699 | ||
![]() |
18d561da0e | ||
![]() |
30b86271ea | ||
![]() |
5f3c35209d | ||
![]() |
2535519830 | ||
![]() |
f4dd3e44b6 | ||
![]() |
11babb9509 | ||
![]() |
e1bedf30bf | ||
![]() |
859682c8d1 | ||
![]() |
804edceec2 | ||
![]() |
9f181014a1 | ||
![]() |
4313fd97aa | ||
![]() |
4e569ad644 | ||
![]() |
b4384a1be3 | ||
![]() |
5b42c91a91 | ||
![]() |
926d394b2f | ||
![]() |
fc5a926892 | ||
![]() |
d2787d4308 | ||
![]() |
8cc170f027 | ||
![]() |
53fa64fd14 | ||
![]() |
8c96dfe1d1 | ||
![]() |
36ae42a011 | ||
![]() |
0181d1e377 | ||
![]() |
3f0a954856 | ||
![]() |
2875e84cb5 | ||
![]() |
7917bf55ff | ||
![]() |
ea0292b911 | ||
![]() |
e6d1ad0ac5 | ||
![]() |
9808ff64e7 | ||
![]() |
f65ddccd6e | ||
![]() |
b763754723 | ||
![]() |
d5dafffc39 | ||
![]() |
bd7c575f26 | ||
![]() |
13f250f630 | ||
![]() |
7a4eb0b37c | ||
![]() |
1e80342c41 | ||
![]() |
7031c47fb2 | ||
![]() |
e431031112 | ||
![]() |
379061f847 | ||
![]() |
beefc51361 |
@@ -1,168 +1,318 @@
|
||||
rtmp
|
||||
edgetpu
|
||||
labelmap
|
||||
rockchip
|
||||
jetson
|
||||
rocm
|
||||
vaapi
|
||||
CUDA
|
||||
hwaccel
|
||||
RTSP
|
||||
Hikvision
|
||||
Dahua
|
||||
Amcrest
|
||||
Reolink
|
||||
Loryta
|
||||
Beelink
|
||||
Celeron
|
||||
vaapi
|
||||
blakeblackshear
|
||||
workdir
|
||||
onvif
|
||||
autotracking
|
||||
openvino
|
||||
tflite
|
||||
deepstack
|
||||
codeproject
|
||||
udev
|
||||
tailscale
|
||||
restream
|
||||
restreaming
|
||||
webrtc
|
||||
ssdlite
|
||||
mobilenet
|
||||
mosquitto
|
||||
datasheet
|
||||
Jellyfin
|
||||
Radeon
|
||||
libva
|
||||
Ubiquiti
|
||||
Unifi
|
||||
Tapo
|
||||
Annke
|
||||
autotracker
|
||||
autotracked
|
||||
variations
|
||||
ONVIF
|
||||
traefik
|
||||
devcontainer
|
||||
rootfs
|
||||
ffprobe
|
||||
autotrack
|
||||
logpipe
|
||||
imread
|
||||
imwrite
|
||||
imencode
|
||||
imutils
|
||||
thresholded
|
||||
timelapse
|
||||
ultrafast
|
||||
sleeptime
|
||||
radeontop
|
||||
vainfo
|
||||
tmpfs
|
||||
homography
|
||||
websockets
|
||||
LIBAVFORMAT
|
||||
NTSC
|
||||
onnxruntime
|
||||
fourcc
|
||||
radeonsi
|
||||
paho
|
||||
imagestream
|
||||
jsonify
|
||||
cgroups
|
||||
sysconf
|
||||
memlimit
|
||||
gpuload
|
||||
nvml
|
||||
setproctitle
|
||||
psutil
|
||||
Kalman
|
||||
frontdoor
|
||||
namedtuples
|
||||
zeep
|
||||
fflags
|
||||
probesize
|
||||
wallclock
|
||||
rknn
|
||||
socs
|
||||
pydantic
|
||||
shms
|
||||
imdecode
|
||||
colormap
|
||||
webui
|
||||
mse
|
||||
jsmpeg
|
||||
unreviewed
|
||||
Chromecast
|
||||
Swipeable
|
||||
flac
|
||||
scroller
|
||||
cmdline
|
||||
toggleable
|
||||
bottombar
|
||||
opencv
|
||||
apexcharts
|
||||
buildx
|
||||
mqtt
|
||||
rawvideo
|
||||
defragment
|
||||
Norfair
|
||||
subclassing
|
||||
yolo
|
||||
tensorrt
|
||||
blackshear
|
||||
stylelint
|
||||
HACS
|
||||
homeassistant
|
||||
hass
|
||||
castable
|
||||
mobiledet
|
||||
framebuffer
|
||||
mjpeg
|
||||
substream
|
||||
codeowner
|
||||
noninteractive
|
||||
restreamed
|
||||
mountpoint
|
||||
fstype
|
||||
OWASP
|
||||
iotop
|
||||
letsencrypt
|
||||
fullchain
|
||||
lsusb
|
||||
iostat
|
||||
usermod
|
||||
balena
|
||||
passwordless
|
||||
debconf
|
||||
dpkg
|
||||
poweroff
|
||||
surveillance
|
||||
qnap
|
||||
homekit
|
||||
colorspace
|
||||
quantisation
|
||||
skylake
|
||||
Cuvid
|
||||
foscam
|
||||
onnx
|
||||
numpy
|
||||
protobuf
|
||||
aarch
|
||||
absdiff
|
||||
airockchip
|
||||
Alloc
|
||||
alpr
|
||||
Amcrest
|
||||
amdgpu
|
||||
chipset
|
||||
referer
|
||||
mpegts
|
||||
webp
|
||||
analyzeduration
|
||||
Annke
|
||||
apexcharts
|
||||
arange
|
||||
argmax
|
||||
argmin
|
||||
argpartition
|
||||
ascontiguousarray
|
||||
astype
|
||||
authelia
|
||||
authentik
|
||||
unichip
|
||||
rebranded
|
||||
udevadm
|
||||
autodetected
|
||||
automations
|
||||
unraid
|
||||
hideable
|
||||
autotrack
|
||||
autotracked
|
||||
autotracker
|
||||
autotracking
|
||||
balena
|
||||
Beelink
|
||||
BGRA
|
||||
BHWC
|
||||
blackshear
|
||||
blakeblackshear
|
||||
bottombar
|
||||
buildx
|
||||
castable
|
||||
cdist
|
||||
Celeron
|
||||
cgroups
|
||||
chipset
|
||||
chromadb
|
||||
Chromecast
|
||||
cmdline
|
||||
codeowner
|
||||
CODEOWNERS
|
||||
codeproject
|
||||
colormap
|
||||
colorspace
|
||||
comms
|
||||
cooldown
|
||||
coro
|
||||
ctypeslib
|
||||
CUDA
|
||||
Cuvid
|
||||
Dahua
|
||||
datasheet
|
||||
debconf
|
||||
deci
|
||||
deepstack
|
||||
defragment
|
||||
devcontainer
|
||||
DEVICEMAP
|
||||
discardcorrupt
|
||||
dpkg
|
||||
dsize
|
||||
dtype
|
||||
ECONNRESET
|
||||
edgetpu
|
||||
facenet
|
||||
fastapi
|
||||
faststart
|
||||
fflags
|
||||
ffprobe
|
||||
fillna
|
||||
flac
|
||||
foscam
|
||||
fourcc
|
||||
framebuffer
|
||||
fregate
|
||||
frégate
|
||||
fromarray
|
||||
frombuffer
|
||||
frontdoor
|
||||
fstype
|
||||
fullchain
|
||||
fullscreen
|
||||
genai
|
||||
generativeai
|
||||
genpts
|
||||
getpid
|
||||
gpuload
|
||||
HACS
|
||||
Hailo
|
||||
hass
|
||||
hconcat
|
||||
healthcheck
|
||||
keepalive
|
||||
hideable
|
||||
Hikvision
|
||||
homeassistant
|
||||
homekit
|
||||
homography
|
||||
hsize
|
||||
hstack
|
||||
httpx
|
||||
hwaccel
|
||||
hwdownload
|
||||
hwmap
|
||||
hwupload
|
||||
iloc
|
||||
imagestream
|
||||
imdecode
|
||||
imencode
|
||||
imread
|
||||
imwrite
|
||||
inpoint
|
||||
interp
|
||||
iostat
|
||||
iotop
|
||||
itemsize
|
||||
Jellyfin
|
||||
jetson
|
||||
jetsons
|
||||
jina
|
||||
jinaai
|
||||
joserfc
|
||||
jsmpeg
|
||||
jsonify
|
||||
Kalman
|
||||
keepalive
|
||||
keepdims
|
||||
labelmap
|
||||
letsencrypt
|
||||
levelname
|
||||
LIBAVFORMAT
|
||||
libedgetpu
|
||||
libnvinfer
|
||||
libva
|
||||
libwebp
|
||||
libx
|
||||
libyolo
|
||||
linalg
|
||||
localzone
|
||||
logpipe
|
||||
Loryta
|
||||
lstsq
|
||||
lsusb
|
||||
markupsafe
|
||||
maxsplit
|
||||
MEMHOSTALLOC
|
||||
memlimit
|
||||
meshgrid
|
||||
metadatas
|
||||
migraphx
|
||||
minilm
|
||||
mjpeg
|
||||
mkfifo
|
||||
mobiledet
|
||||
mobilenet
|
||||
modelpath
|
||||
mosquitto
|
||||
mountpoint
|
||||
movflags
|
||||
mpegts
|
||||
mqtt
|
||||
mse
|
||||
msenc
|
||||
namedtuples
|
||||
nbytes
|
||||
nchw
|
||||
ndarray
|
||||
ndimage
|
||||
nethogs
|
||||
newaxis
|
||||
nhwc
|
||||
NOBLOCK
|
||||
nobuffer
|
||||
nokey
|
||||
NONBLOCK
|
||||
noninteractive
|
||||
noprint
|
||||
Norfair
|
||||
nptype
|
||||
NTSC
|
||||
numpy
|
||||
nvenc
|
||||
nvhost
|
||||
nvml
|
||||
nvmpi
|
||||
ollama
|
||||
onnx
|
||||
onnxruntime
|
||||
onvif
|
||||
ONVIF
|
||||
openai
|
||||
opencv
|
||||
openvino
|
||||
OWASP
|
||||
paddleocr
|
||||
paho
|
||||
passwordless
|
||||
popleft
|
||||
posthog
|
||||
postprocess
|
||||
poweroff
|
||||
preexec
|
||||
probesize
|
||||
protobuf
|
||||
pstate
|
||||
psutil
|
||||
pubkey
|
||||
putenv
|
||||
pycache
|
||||
pydantic
|
||||
pyobj
|
||||
pysqlite
|
||||
pytz
|
||||
pywebpush
|
||||
qnap
|
||||
quantisation
|
||||
Radeon
|
||||
radeonsi
|
||||
radeontop
|
||||
rawvideo
|
||||
rcond
|
||||
RDONLY
|
||||
rebranded
|
||||
referer
|
||||
reindex
|
||||
Reolink
|
||||
restream
|
||||
restreamed
|
||||
restreaming
|
||||
rkmpp
|
||||
rknn
|
||||
rkrga
|
||||
rockchip
|
||||
rocm
|
||||
rocminfo
|
||||
rootfs
|
||||
rtmp
|
||||
RTSP
|
||||
ruamel
|
||||
scroller
|
||||
setproctitle
|
||||
setpts
|
||||
shms
|
||||
SIGUSR
|
||||
skylake
|
||||
sleeptime
|
||||
SNDMORE
|
||||
socs
|
||||
sqliteq
|
||||
sqlitevecq
|
||||
ssdlite
|
||||
statm
|
||||
stimeout
|
||||
stylelint
|
||||
subclassing
|
||||
substream
|
||||
superfast
|
||||
surveillance
|
||||
svscan
|
||||
Swipeable
|
||||
sysconf
|
||||
tailscale
|
||||
Tapo
|
||||
tensorrt
|
||||
tflite
|
||||
thresholded
|
||||
timelapse
|
||||
titlecase
|
||||
tmpfs
|
||||
tobytes
|
||||
toggleable
|
||||
traefik
|
||||
tzlocal
|
||||
Ubiquiti
|
||||
udev
|
||||
udevadm
|
||||
ultrafast
|
||||
unichip
|
||||
unidecode
|
||||
Unifi
|
||||
unixepoch
|
||||
unraid
|
||||
unreviewed
|
||||
userdata
|
||||
usermod
|
||||
uvicorn
|
||||
vaapi
|
||||
vainfo
|
||||
variations
|
||||
vbios
|
||||
vconcat
|
||||
vitb
|
||||
vstream
|
||||
vsync
|
||||
wallclock
|
||||
webp
|
||||
webpush
|
||||
webrtc
|
||||
websockets
|
||||
webui
|
||||
werkzeug
|
||||
workdir
|
||||
WRONLY
|
||||
wsgirefserver
|
||||
wsgiutils
|
||||
wsize
|
||||
xaddr
|
||||
xmaxs
|
||||
xmins
|
||||
XPUB
|
||||
XSUB
|
||||
ymaxs
|
||||
ymins
|
||||
yolo
|
||||
yolonas
|
||||
yolox
|
||||
zeep
|
||||
zerolatency
|
@@ -8,11 +8,27 @@
|
||||
"overrideCommand": false,
|
||||
"remoteUser": "vscode",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/common-utils:1": {}
|
||||
"ghcr.io/devcontainers/features/common-utils:2": {}
|
||||
// Uncomment the following lines to use ONNX Runtime with CUDA support
|
||||
// "ghcr.io/devcontainers/features/nvidia-cuda:1": {
|
||||
// "installCudnn": true,
|
||||
// "installNvtx": true,
|
||||
// "installToolkit": true,
|
||||
// "cudaVersion": "12.5",
|
||||
// "cudnnVersion": "9.4.0.58"
|
||||
// },
|
||||
// "./features/onnxruntime-gpu": {}
|
||||
},
|
||||
"forwardPorts": [8080, 5000, 5001, 5173, 8554, 8555],
|
||||
"forwardPorts": [
|
||||
8971,
|
||||
5000,
|
||||
5001,
|
||||
5173,
|
||||
8554,
|
||||
8555
|
||||
],
|
||||
"portsAttributes": {
|
||||
"8080": {
|
||||
"8971": {
|
||||
"label": "External NGINX",
|
||||
"onAutoForward": "silent"
|
||||
},
|
||||
@@ -52,7 +68,8 @@
|
||||
"csstools.postcss",
|
||||
"blanu.vscode-styled-jsx",
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"charliermarsh.ruff"
|
||||
"charliermarsh.ruff",
|
||||
"eamodio.gitlens"
|
||||
],
|
||||
"settings": {
|
||||
"remote.autoForwardPorts": false,
|
||||
@@ -63,10 +80,18 @@
|
||||
"editor.formatOnType": true,
|
||||
"python.testing.pytestEnabled": false,
|
||||
"python.testing.unittestEnabled": true,
|
||||
"python.testing.unittestArgs": ["-v", "-s", "./frigate/test"],
|
||||
"python.testing.unittestArgs": [
|
||||
"-v",
|
||||
"-s",
|
||||
"./frigate/test"
|
||||
],
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"eslint.workingDirectories": ["./web"],
|
||||
"isort.args": ["--settings-path=./pyproject.toml"],
|
||||
"eslint.workingDirectories": [
|
||||
"./web"
|
||||
],
|
||||
"isort.args": [
|
||||
"--settings-path=./pyproject.toml"
|
||||
],
|
||||
"[python]": {
|
||||
"editor.defaultFormatter": "charliermarsh.ruff",
|
||||
"editor.formatOnSave": true,
|
||||
@@ -85,9 +110,16 @@
|
||||
],
|
||||
"editor.tabSize": 2
|
||||
},
|
||||
"cSpell.ignoreWords": ["rtmp"],
|
||||
"cSpell.words": ["preact", "astype", "hwaccel", "mqtt"]
|
||||
"cSpell.ignoreWords": [
|
||||
"rtmp"
|
||||
],
|
||||
"cSpell.words": [
|
||||
"preact",
|
||||
"astype",
|
||||
"hwaccel",
|
||||
"mqtt"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"id": "onnxruntime-gpu",
|
||||
"version": "0.0.1",
|
||||
"name": "ONNX Runtime GPU (Nvidia)",
|
||||
"description": "Installs ONNX Runtime for Nvidia GPUs.",
|
||||
"documentationURL": "",
|
||||
"options": {
|
||||
"version": {
|
||||
"type": "string",
|
||||
"proposals": [
|
||||
"latest",
|
||||
"1.20.1",
|
||||
"1.20.0"
|
||||
],
|
||||
"default": "latest",
|
||||
"description": "Version of ONNX Runtime to install"
|
||||
}
|
||||
},
|
||||
"installsAfter": [
|
||||
"ghcr.io/devcontainers/features/nvidia-cuda"
|
||||
]
|
||||
}
|
15
.devcontainer/features/onnxruntime-gpu/install.sh
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
VERSION=${VERSION}
|
||||
|
||||
python3 -m pip config set global.break-system-packages true
|
||||
# if VERSION == "latest" or VERSION is empty, install the latest version
|
||||
if [ "$VERSION" == "latest" ] || [ -z "$VERSION" ]; then
|
||||
python3 -m pip install onnxruntime-gpu
|
||||
else
|
||||
python3 -m pip install onnxruntime-gpu==$VERSION
|
||||
fi
|
||||
|
||||
echo "Done!"
|
@@ -3,10 +3,12 @@
|
||||
set -euxo pipefail
|
||||
|
||||
# Cleanup the old github host key
|
||||
sed -i -e '/AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31\/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi\/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==/d' ~/.ssh/known_hosts
|
||||
# Add new github host key
|
||||
curl -L https://api.github.com/meta | jq -r '.ssh_keys | .[]' | \
|
||||
sed -e 's/^/github.com /' >> ~/.ssh/known_hosts
|
||||
if [[ -f ~/.ssh/known_hosts ]]; then
|
||||
# Add new github host key
|
||||
sed -i -e '/AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31\/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi\/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==/d' ~/.ssh/known_hosts
|
||||
curl -L https://api.github.com/meta | jq -r '.ssh_keys | .[]' | \
|
||||
sed -e 's/^/github.com /' >> ~/.ssh/known_hosts
|
||||
fi
|
||||
|
||||
# Frigate normal container runs as root, so it have permission to create
|
||||
# the folders. But the devcontainer runs as the host user, so we need to
|
||||
@@ -17,7 +19,7 @@ sudo chown -R "$(id -u):$(id -g)" /media/frigate
|
||||
# When started as a service, LIBAVFORMAT_VERSION_MAJOR is defined in the
|
||||
# s6 service file. For dev, where frigate is started from an interactive
|
||||
# shell, we define it in .bashrc instead.
|
||||
echo 'export LIBAVFORMAT_VERSION_MAJOR=$(ffmpeg -version | grep -Po "libavformat\W+\K\d+")' >> $HOME/.bashrc
|
||||
echo 'export LIBAVFORMAT_VERSION_MAJOR=$("$(python3 /usr/local/ffmpeg/get_ffmpeg_path.py)" -version | grep -Po "libavformat\W+\K\d+")' >> "$HOME/.bashrc"
|
||||
|
||||
make version
|
||||
|
||||
|
60
.github/DISCUSSION_TEMPLATE/camera-support.yml
vendored
@@ -1,6 +1,16 @@
|
||||
title: "[Camera Support]: "
|
||||
labels: ["support", "triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Use this form for support or questions for an issue with your cameras.
|
||||
|
||||
Before submitting your support request, please [search the discussions][discussions], read the [official Frigate documentation][docs], and read the [Frigate FAQ][faq] pinned at the Discussion page to see if your question has already been answered by the community.
|
||||
|
||||
[discussions]: https://www.github.com/blakeblackshear/frigate/discussions
|
||||
[docs]: https://docs.frigate.video
|
||||
[faq]: https://github.com/blakeblackshear/frigate/discussions/12724
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
@@ -11,9 +21,15 @@ body:
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: Visible on the System page in the Web UI
|
||||
description: Visible on the System page in the Web UI. Please include the full version including the build identifier (eg. 0.14.0-ea36ds1)
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: What browser(s) are you using?
|
||||
placeholder: Google Chrome 88.0.4324.150
|
||||
description: >
|
||||
Provide the full name and don't forget to add the version!
|
||||
- type: textarea
|
||||
id: config
|
||||
attributes:
|
||||
@@ -23,10 +39,18 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
id: frigatelogs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
label: Relevant Frigate log output
|
||||
description: Please copy and paste any relevant Frigate log output. Include logs before and after your exact error when possible. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: go2rtclogs
|
||||
attributes:
|
||||
label: Relevant go2rtc log output
|
||||
description: Please copy and paste any relevant go2rtc log output. Include logs before and after your exact error when possible. Logs can be viewed via the Frigate UI, Docker, or the go2rtc dashboard. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
@@ -34,7 +58,7 @@ body:
|
||||
id: ffprobe
|
||||
attributes:
|
||||
label: FFprobe output from your camera
|
||||
description: Run `ffprobe <camera_url>` and provide output below
|
||||
description: Run `ffprobe <camera_url>` from within the Frigate container if possible, and provide output below
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
@@ -49,7 +73,7 @@ body:
|
||||
attributes:
|
||||
label: Operating system
|
||||
options:
|
||||
- HassOS
|
||||
- Home Assistant OS
|
||||
- Debian
|
||||
- Other Linux
|
||||
- Proxmox
|
||||
@@ -63,20 +87,23 @@ body:
|
||||
attributes:
|
||||
label: Install method
|
||||
options:
|
||||
- HassOS Addon
|
||||
- Home Assistant Add-on
|
||||
- Docker Compose
|
||||
- Docker CLI
|
||||
- Proxmox via Docker
|
||||
- Proxmox via TTeck Script
|
||||
- Windows WSL2
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: coral
|
||||
id: object-detector
|
||||
attributes:
|
||||
label: Coral version
|
||||
label: Object Detector
|
||||
options:
|
||||
- USB
|
||||
- PCIe
|
||||
- M.2
|
||||
- Dev Board
|
||||
- Coral
|
||||
- OpenVino
|
||||
- TensorRT
|
||||
- RKNN
|
||||
- Other
|
||||
- CPU (no coral)
|
||||
validations:
|
||||
@@ -98,6 +125,13 @@ body:
|
||||
description: Dahua, hikvision, amcrest, reolink, etc and model number
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots of the Frigate UI's System metrics pages
|
||||
description: Drag and drop for images is possible in this field. Please post screenshots of at least General and Cameras tabs.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: other
|
||||
attributes:
|
||||
|
58
.github/DISCUSSION_TEMPLATE/config-support.yml
vendored
@@ -1,6 +1,16 @@
|
||||
title: "[Config Support]: "
|
||||
labels: ["support", "triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Use this form for support or questions related to Frigate's configuration and config file.
|
||||
|
||||
Before submitting your support request, please [search the discussions][discussions], read the [official Frigate documentation][docs], and read the [Frigate FAQ][faq] pinned at the Discussion page to see if your question has already been answered by the community.
|
||||
|
||||
[discussions]: https://www.github.com/blakeblackshear/frigate/discussions
|
||||
[docs]: https://docs.frigate.video
|
||||
[faq]: https://github.com/blakeblackshear/frigate/discussions/12724
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
@@ -11,7 +21,7 @@ body:
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: Visible on the System page in the Web UI
|
||||
description: Visible on the System page in the Web UI. Please include the full version including the build identifier (eg. 0.14.0-ea36ds1)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
@@ -23,10 +33,18 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
id: frigatelogs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
label: Relevant Frigate log output
|
||||
description: Please copy and paste any relevant Frigate log output. Include logs before and after your exact error when possible. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: go2rtclogs
|
||||
attributes:
|
||||
label: Relevant go2rtc log output
|
||||
description: Please copy and paste any relevant go2rtc log output. Include logs before and after your exact error when possible. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
@@ -41,7 +59,7 @@ body:
|
||||
attributes:
|
||||
label: Operating system
|
||||
options:
|
||||
- HassOS
|
||||
- Home Assistant OS
|
||||
- Debian
|
||||
- Other Linux
|
||||
- Proxmox
|
||||
@@ -55,24 +73,40 @@ body:
|
||||
attributes:
|
||||
label: Install method
|
||||
options:
|
||||
- HassOS Addon
|
||||
- Home Assistant Add-on
|
||||
- Docker Compose
|
||||
- Docker CLI
|
||||
- Proxmox via Docker
|
||||
- Proxmox via TTeck Script
|
||||
- Windows WSL2
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: docker
|
||||
attributes:
|
||||
label: docker-compose file or Docker CLI command
|
||||
description: This will be automatically formatted into code, so no need for backticks.
|
||||
render: yaml
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: coral
|
||||
id: object-detector
|
||||
attributes:
|
||||
label: Coral version
|
||||
label: Object Detector
|
||||
options:
|
||||
- USB
|
||||
- PCIe
|
||||
- M.2
|
||||
- Dev Board
|
||||
- Coral
|
||||
- OpenVino
|
||||
- TensorRT
|
||||
- RKNN
|
||||
- Other
|
||||
- CPU (no coral)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots of the Frigate UI's System metrics pages
|
||||
description: Drag and drop or simple cut/paste is possible in this field
|
||||
- type: textarea
|
||||
id: other
|
||||
attributes:
|
||||
|
56
.github/DISCUSSION_TEMPLATE/detector-support.yml
vendored
@@ -1,6 +1,16 @@
|
||||
title: "[Detector Support]: "
|
||||
labels: ["support", "triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Use this form for support or questions related to Frigate's object detectors.
|
||||
|
||||
Before submitting your support request, please [search the discussions][discussions], read the [official Frigate documentation][docs], and read the [Frigate FAQ][faq] pinned at the Discussion page to see if your question has already been answered by the community.
|
||||
|
||||
[discussions]: https://www.github.com/blakeblackshear/frigate/discussions
|
||||
[docs]: https://docs.frigate.video
|
||||
[faq]: https://github.com/blakeblackshear/frigate/discussions/12724
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
@@ -11,7 +21,7 @@ body:
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: Visible on the System page in the Web UI
|
||||
description: Visible on the System page in the Web UI. Please include the full version including the build identifier (eg. 0.14.0-ea36ds1)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
@@ -31,50 +41,46 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
id: frigatelogs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
label: Relevant Frigate log output
|
||||
description: Please copy and paste any relevant Frigate log output. Include logs before and after your exact error when possible. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
options:
|
||||
- HassOS
|
||||
- Debian
|
||||
- Other Linux
|
||||
- Proxmox
|
||||
- UNRAID
|
||||
- Windows
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: install-method
|
||||
attributes:
|
||||
label: Install method
|
||||
options:
|
||||
- HassOS Addon
|
||||
- Home Assistant Add-on
|
||||
- Docker Compose
|
||||
- Docker CLI
|
||||
- Proxmox via Docker
|
||||
- Proxmox via TTeck Script
|
||||
- Windows WSL2
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: coral
|
||||
id: object-detector
|
||||
attributes:
|
||||
label: Coral version
|
||||
label: Object Detector
|
||||
options:
|
||||
- USB
|
||||
- PCIe
|
||||
- M.2
|
||||
- Dev Board
|
||||
- Coral
|
||||
- OpenVino
|
||||
- TensorRT
|
||||
- RKNN
|
||||
- Other
|
||||
- CPU (no coral)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots of the Frigate UI's System metrics pages
|
||||
description: Drag and drop for images is possible in this field. Please post screenshots of at least General and Cameras tabs.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: other
|
||||
attributes:
|
||||
|
78
.github/DISCUSSION_TEMPLATE/general-support.yml
vendored
@@ -1,6 +1,16 @@
|
||||
title: "[Support]: "
|
||||
labels: ["support", "triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Use this form for support for issues that don't fall into any specific category.
|
||||
|
||||
Before submitting your support request, please [search the discussions][discussions], read the [official Frigate documentation][docs], and read the [Frigate FAQ][faq] pinned at the Discussion page to see if your question has already been answered by the community.
|
||||
|
||||
[discussions]: https://www.github.com/blakeblackshear/frigate/discussions
|
||||
[docs]: https://docs.frigate.video
|
||||
[faq]: https://github.com/blakeblackshear/frigate/discussions/12724
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
@@ -11,9 +21,15 @@ body:
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: Visible on the System page in the Web UI
|
||||
description: Visible on the System page in the Web UI. Please include the full version including the build identifier (eg. 0.14.0-ea36ds1)
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: What browser(s) are you using?
|
||||
placeholder: Google Chrome 88.0.4324.150
|
||||
description: >
|
||||
Provide the full name and don't forget to add the version!
|
||||
- type: textarea
|
||||
id: config
|
||||
attributes:
|
||||
@@ -23,10 +39,18 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
id: frigatelogs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
label: Relevant Frigate log output
|
||||
description: Please copy and paste any relevant Frigate log output. Include logs before and after your exact error when possible. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: go2rtclogs
|
||||
attributes:
|
||||
label: Relevant go2rtc log output
|
||||
description: Please copy and paste any relevant go2rtc log output. Include logs before and after your exact error when possible. Logs can be viewed via the Frigate UI, Docker, or the go2rtc dashboard. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
@@ -34,7 +58,7 @@ body:
|
||||
id: ffprobe
|
||||
attributes:
|
||||
label: FFprobe output from your camera
|
||||
description: Run `ffprobe <camera_url>` and provide output below
|
||||
description: Run `ffprobe <camera_url>` from within the Frigate container if possible, and provide output below
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
@@ -44,39 +68,36 @@ body:
|
||||
label: Frigate stats
|
||||
description: Output from frigate's /api/stats endpoint
|
||||
render: json
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
options:
|
||||
- HassOS
|
||||
- Debian
|
||||
- Other Linux
|
||||
- Proxmox
|
||||
- UNRAID
|
||||
- Windows
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: install-method
|
||||
attributes:
|
||||
label: Install method
|
||||
options:
|
||||
- HassOS Addon
|
||||
- Home Assistant Add-on
|
||||
- Docker Compose
|
||||
- Docker CLI
|
||||
- Proxmox via Docker
|
||||
- Proxmox via TTeck Script
|
||||
- Windows WSL2
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: docker
|
||||
attributes:
|
||||
label: docker-compose file or Docker CLI command
|
||||
description: This will be automatically formatted into code, so no need for backticks.
|
||||
render: yaml
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: coral
|
||||
id: object-detector
|
||||
attributes:
|
||||
label: Coral version
|
||||
label: Object Detector
|
||||
options:
|
||||
- USB
|
||||
- PCIe
|
||||
- M.2
|
||||
- Dev Board
|
||||
- Coral
|
||||
- OpenVino
|
||||
- TensorRT
|
||||
- RKNN
|
||||
- Other
|
||||
- CPU (no coral)
|
||||
validations:
|
||||
@@ -98,6 +119,11 @@ body:
|
||||
description: Dahua, hikvision, amcrest, reolink, etc and model number
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots of the Frigate UI's System metrics pages
|
||||
description: Drag and drop for images is possible in this field
|
||||
- type: textarea
|
||||
id: other
|
||||
attributes:
|
||||
|
@@ -1,6 +1,16 @@
|
||||
title: "[HW Accel Support]: "
|
||||
labels: ["support", "triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Use this form to submit a support request for hardware acceleration issues.
|
||||
|
||||
Before submitting your support request, please [search the discussions][discussions], read the [official Frigate documentation][docs], and read the [Frigate FAQ][faq] pinned at the Discussion page to see if your question has already been answered by the community.
|
||||
|
||||
[discussions]: https://www.github.com/blakeblackshear/frigate/discussions
|
||||
[docs]: https://docs.frigate.video
|
||||
[faq]: https://github.com/blakeblackshear/frigate/discussions/12724
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
@@ -11,7 +21,7 @@ body:
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: Visible on the System page in the Web UI
|
||||
description: Visible on the System page in the Web UI. Please include the full version including the build identifier (eg. 0.14.0-ea36ds1)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
@@ -31,10 +41,18 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
id: frigatelogs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
label: Relevant Frigate log output
|
||||
description: Please copy and paste any relevant Frigate log output. Include logs before and after your exact error when possible. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: go2rtclogs
|
||||
attributes:
|
||||
label: Relevant go2rtc log output
|
||||
description: Please copy and paste any relevant go2rtc log output. Include logs before and after your exact error when possible. Logs can be viewed via the Frigate UI, Docker, or the go2rtc dashboard. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
@@ -42,32 +60,34 @@ body:
|
||||
id: ffprobe
|
||||
attributes:
|
||||
label: FFprobe output from your camera
|
||||
description: Run `ffprobe <camera_url>` and provide output below
|
||||
description: Run `ffprobe <camera_url>` from within the Frigate container if possible, and provide output below
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
options:
|
||||
- HassOS
|
||||
- Debian
|
||||
- Other Linux
|
||||
- Proxmox
|
||||
- UNRAID
|
||||
- Windows
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: install-method
|
||||
attributes:
|
||||
label: Install method
|
||||
options:
|
||||
- HassOS Addon
|
||||
- Home Assistant Add-on
|
||||
- Docker Compose
|
||||
- Docker CLI
|
||||
- Proxmox via Docker
|
||||
- Proxmox via TTeck Script
|
||||
- Windows WSL2
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: object-detector
|
||||
attributes:
|
||||
label: Object Detector
|
||||
options:
|
||||
- Coral
|
||||
- OpenVino
|
||||
- TensorRT
|
||||
- RKNN
|
||||
- Other
|
||||
- CPU (no coral)
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
@@ -87,6 +107,13 @@ body:
|
||||
description: Dahua, hikvision, amcrest, reolink, etc and model number
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots of the Frigate UI's System metrics pages
|
||||
description: Drag and drop for images is possible in this field. Please post screenshots of at least General and Cameras tabs.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: other
|
||||
attributes:
|
||||
|
14
.github/DISCUSSION_TEMPLATE/question.yml
vendored
@@ -1,9 +1,21 @@
|
||||
title: "[Question]: "
|
||||
labels: ["question"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Use this form for questions you have about Frigate.
|
||||
|
||||
Before submitting your question, please [search the discussions][discussions], read the [official Frigate documentation][docs], and read the [Frigate FAQ][faq] pinned at the Discussion page to see if your question has already been answered by the community.
|
||||
|
||||
**If you are looking for support, start a new discussion and use a support category.**
|
||||
|
||||
[discussions]: https://www.github.com/blakeblackshear/frigate/discussions
|
||||
[docs]: https://docs.frigate.video
|
||||
[faq]: https://github.com/blakeblackshear/frigate/discussions/12724
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: "What is your question:"
|
||||
label: "What is your question?"
|
||||
validations:
|
||||
required: true
|
||||
|
149
.github/DISCUSSION_TEMPLATE/report-a-bug.yml
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
title: "[Bug]: "
|
||||
labels: ["bug", "triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Use this form to submit a reproducible bug in Frigate or Frigate's UI.
|
||||
|
||||
Before submitting your bug report, please ask the AI with the "Ask AI" button on the [official documentation site][ai] about your issue, [search the discussions][discussions], look at recent open and closed [pull requests][prs], read the [official Frigate documentation][docs], and read the [Frigate FAQ][faq] pinned at the Discussion page to see if your bug has already been fixed by the developers or reported by the community.
|
||||
|
||||
**If you are unsure if your issue is actually a bug or not, please submit a support request first.**
|
||||
|
||||
[discussions]: https://www.github.com/blakeblackshear/frigate/discussions
|
||||
[prs]: https://www.github.com/blakeblackshear/frigate/pulls
|
||||
[docs]: https://docs.frigate.video
|
||||
[faq]: https://github.com/blakeblackshear/frigate/discussions/12724
|
||||
[ai]: https://docs.frigate.video
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Checklist
|
||||
description: Please verify that you've followed these steps
|
||||
options:
|
||||
- label: I have updated to the latest available Frigate version.
|
||||
required: true
|
||||
- label: I have cleared the cache of my browser.
|
||||
required: true
|
||||
- label: I have tried a different browser to see if it is related to my browser.
|
||||
required: true
|
||||
- label: I have tried reproducing the issue in [incognito mode](https://www.computerworld.com/article/1719851/how-to-go-incognito-in-chrome-firefox-safari-and-edge.html) to rule out problems with any third party extensions or plugins I have installed.
|
||||
- label: I have asked the AI at https://docs.frigate.video about my issue.
|
||||
required: true
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe the problem you are having
|
||||
description: Provide a clear and concise description of what the bug is.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: steps
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: |
|
||||
Please tell us exactly how to reproduce your issue.
|
||||
Provide clear and concise step by step instructions and add code snippets if needed.
|
||||
value: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
...
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: Visible on the System page in the Web UI. Please include the full version including the build identifier (eg. 0.14.0-ea36ds1)
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: In which browser(s) are you experiencing the issue with?
|
||||
placeholder: Google Chrome 88.0.4324.150
|
||||
description: >
|
||||
Provide the full name and don't forget to add the version!
|
||||
- type: textarea
|
||||
id: config
|
||||
attributes:
|
||||
label: Frigate config file
|
||||
description: This will be automatically formatted into code, so no need for backticks.
|
||||
render: yaml
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: docker
|
||||
attributes:
|
||||
label: docker-compose file or Docker CLI command
|
||||
description: This will be automatically formatted into code, so no need for backticks.
|
||||
render: yaml
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: frigatelogs
|
||||
attributes:
|
||||
label: Relevant Frigate log output
|
||||
description: Please copy and paste any relevant Frigate log output. Include logs before and after your exact error when possible. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: go2rtclogs
|
||||
attributes:
|
||||
label: Relevant go2rtc log output
|
||||
description: Please copy and paste any relevant go2rtc log output. Include logs before and after your exact error when possible. Logs can be viewed via the Frigate UI, Docker, or the go2rtc dashboard. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
options:
|
||||
- Home Assistant OS
|
||||
- Debian
|
||||
- Other Linux
|
||||
- Proxmox
|
||||
- UNRAID
|
||||
- Windows
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: install-method
|
||||
attributes:
|
||||
label: Install method
|
||||
options:
|
||||
- Home Assistant Add-on
|
||||
- Docker Compose
|
||||
- Docker CLI
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: network
|
||||
attributes:
|
||||
label: Network connection
|
||||
options:
|
||||
- Wired
|
||||
- Wireless
|
||||
- Mixed
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: camera
|
||||
attributes:
|
||||
label: Camera make and model
|
||||
description: Dahua, hikvision, amcrest, reolink, etc and model number
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots of the Frigate UI's System metrics pages
|
||||
description: Drag and drop for images is possible in this field. Please post screenshots of all tabs.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: other
|
||||
attributes:
|
||||
label: Any other information that may be helpful
|
1
.github/FUNDING.yml
vendored
@@ -1,3 +1,4 @@
|
||||
github:
|
||||
- blakeblackshear
|
||||
- NickM-27
|
||||
- hawkeye217
|
||||
|
5
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -2,4 +2,7 @@ blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Frigate Support
|
||||
url: https://github.com/blakeblackshear/frigate/discussions/new/choose
|
||||
about: Get support for setting up or troubelshooting Frigate.
|
||||
about: Get support for setting up or troubleshooting Frigate.
|
||||
- name: Frigate Bug Report
|
||||
url: https://github.com/blakeblackshear/frigate/discussions/new/choose
|
||||
about: Report a specific UI or backend bug.
|
||||
|
6
.github/actions/setup/action.yml
vendored
@@ -5,7 +5,7 @@ inputs:
|
||||
required: true
|
||||
outputs:
|
||||
image-name:
|
||||
value: ghcr.io/${{ steps.lowercaseRepo.outputs.lowercase }}:${{ github.ref_name }}-${{ steps.create-short-sha.outputs.SHORT_SHA }}
|
||||
value: ghcr.io/${{ steps.lowercaseRepo.outputs.lowercase }}:${{ steps.create-short-sha.outputs.SHORT_SHA }}
|
||||
cache-name:
|
||||
value: ghcr.io/${{ steps.lowercaseRepo.outputs.lowercase }}:cache
|
||||
runs:
|
||||
@@ -33,9 +33,9 @@ runs:
|
||||
with:
|
||||
string: ${{ github.repository }}
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc
|
||||
with:
|
||||
|
39
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
## Proposed change
|
||||
<!--
|
||||
Thank you!
|
||||
|
||||
If you're introducing a new feature or significantly refactoring existing functionality,
|
||||
we encourage you to start a discussion first. This helps ensure your idea aligns with
|
||||
Frigate's development goals.
|
||||
|
||||
Describe what this pull request does and how it will benefit users of Frigate.
|
||||
Please describe in detail any considerations, breaking changes, etc. that are
|
||||
made in this pull request.
|
||||
-->
|
||||
|
||||
|
||||
## Type of change
|
||||
|
||||
- [ ] Dependency upgrade
|
||||
- [ ] Bugfix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature
|
||||
- [ ] Breaking change (fix/feature causing existing functionality to break)
|
||||
- [ ] Code quality improvements to existing code
|
||||
- [ ] Documentation Update
|
||||
|
||||
## Additional information
|
||||
|
||||
- This PR fixes or closes issue: fixes #
|
||||
- This PR is related to issue:
|
||||
|
||||
## Checklist
|
||||
|
||||
<!--
|
||||
Put an `x` in the boxes that apply.
|
||||
-->
|
||||
|
||||
- [ ] The code change is tested and works locally.
|
||||
- [ ] Local tests pass. **Your PR cannot be merged unless tests pass**
|
||||
- [ ] There is no commented out code in this PR.
|
||||
- [ ] UI changes including text have used i18n keys and have been added to the `en` locale.
|
||||
- [ ] The code has been formatted using Ruff (`ruff format frigate`)
|
218
.github/workflows/ci.yml
vendored
@@ -6,6 +6,8 @@ on:
|
||||
branches:
|
||||
- dev
|
||||
- master
|
||||
paths-ignore:
|
||||
- "docs/**"
|
||||
|
||||
# only run the latest commit to avoid cache overwrites
|
||||
concurrency:
|
||||
@@ -17,11 +19,13 @@ env:
|
||||
|
||||
jobs:
|
||||
amd64_build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
name: AMD64 Build
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up QEMU and Buildx
|
||||
id: setup
|
||||
uses: ./.github/actions/setup
|
||||
@@ -37,12 +41,15 @@ jobs:
|
||||
target: frigate
|
||||
tags: ${{ steps.setup.outputs.image-name }}-amd64
|
||||
cache-from: type=registry,ref=${{ steps.setup.outputs.cache-name }}-amd64
|
||||
cache-to: type=registry,ref=${{ steps.setup.outputs.cache-name }}-amd64,mode=max
|
||||
arm64_build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04-arm
|
||||
name: ARM Build
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up QEMU and Buildx
|
||||
id: setup
|
||||
uses: ./.github/actions/setup
|
||||
@@ -60,8 +67,9 @@ jobs:
|
||||
${{ steps.setup.outputs.image-name }}-standard-arm64
|
||||
cache-from: type=registry,ref=${{ steps.setup.outputs.cache-name }}-arm64
|
||||
- name: Build and push RPi build
|
||||
uses: docker/bake-action@v4
|
||||
uses: docker/bake-action@v6
|
||||
with:
|
||||
source: .
|
||||
push: true
|
||||
targets: rpi
|
||||
files: docker/rpi/rpi.hcl
|
||||
@@ -69,75 +77,45 @@ jobs:
|
||||
rpi.tags=${{ steps.setup.outputs.image-name }}-rpi
|
||||
*.cache-from=type=registry,ref=${{ steps.setup.outputs.cache-name }}-arm64
|
||||
*.cache-to=type=registry,ref=${{ steps.setup.outputs.cache-name }}-arm64,mode=max
|
||||
- name: Build and push Rockchip build
|
||||
uses: docker/bake-action@v3
|
||||
with:
|
||||
push: true
|
||||
targets: rk
|
||||
files: docker/rockchip/rk.hcl
|
||||
set: |
|
||||
rk.tags=${{ steps.setup.outputs.image-name }}-rk
|
||||
*.cache-from=type=gha
|
||||
jetson_jp4_build:
|
||||
runs-on: ubuntu-latest
|
||||
name: Jetson Jetpack 4
|
||||
jetson_jp6_build:
|
||||
runs-on: ubuntu-22.04-arm
|
||||
name: Jetson Jetpack 6
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up QEMU and Buildx
|
||||
id: setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push TensorRT (Jetson, Jetpack 4)
|
||||
- name: Build and push TensorRT (Jetson, Jetpack 6)
|
||||
env:
|
||||
ARCH: arm64
|
||||
BASE_IMAGE: timongentzsch/l4t-ubuntu20-opencv:latest
|
||||
SLIM_BASE: timongentzsch/l4t-ubuntu20-opencv:latest
|
||||
TRT_BASE: timongentzsch/l4t-ubuntu20-opencv:latest
|
||||
uses: docker/bake-action@v4
|
||||
BASE_IMAGE: nvcr.io/nvidia/tensorrt:23.12-py3-igpu
|
||||
SLIM_BASE: nvcr.io/nvidia/tensorrt:23.12-py3-igpu
|
||||
TRT_BASE: nvcr.io/nvidia/tensorrt:23.12-py3-igpu
|
||||
uses: docker/bake-action@v6
|
||||
with:
|
||||
source: .
|
||||
push: true
|
||||
targets: tensorrt
|
||||
files: docker/tensorrt/trt.hcl
|
||||
set: |
|
||||
tensorrt.tags=${{ steps.setup.outputs.image-name }}-tensorrt-jp4
|
||||
*.cache-from=type=registry,ref=${{ steps.setup.outputs.cache-name }}-jp4
|
||||
*.cache-to=type=registry,ref=${{ steps.setup.outputs.cache-name }}-jp4,mode=max
|
||||
jetson_jp5_build:
|
||||
runs-on: ubuntu-latest
|
||||
name: Jetson Jetpack 5
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up QEMU and Buildx
|
||||
id: setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push TensorRT (Jetson, Jetpack 5)
|
||||
env:
|
||||
ARCH: arm64
|
||||
BASE_IMAGE: nvcr.io/nvidia/l4t-tensorrt:r8.5.2-runtime
|
||||
SLIM_BASE: nvcr.io/nvidia/l4t-tensorrt:r8.5.2-runtime
|
||||
TRT_BASE: nvcr.io/nvidia/l4t-tensorrt:r8.5.2-runtime
|
||||
uses: docker/bake-action@v4
|
||||
with:
|
||||
push: true
|
||||
targets: tensorrt
|
||||
files: docker/tensorrt/trt.hcl
|
||||
set: |
|
||||
tensorrt.tags=${{ steps.setup.outputs.image-name }}-tensorrt-jp5
|
||||
*.cache-from=type=registry,ref=${{ steps.setup.outputs.cache-name }}-jp5
|
||||
*.cache-to=type=registry,ref=${{ steps.setup.outputs.cache-name }}-jp5,mode=max
|
||||
tensorrt.tags=${{ steps.setup.outputs.image-name }}-tensorrt-jp6
|
||||
*.cache-from=type=registry,ref=${{ steps.setup.outputs.cache-name }}-jp6
|
||||
*.cache-to=type=registry,ref=${{ steps.setup.outputs.cache-name }}-jp6,mode=max
|
||||
amd64_extra_builds:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
name: AMD64 Extra Build
|
||||
needs:
|
||||
- amd64_build
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up QEMU and Buildx
|
||||
id: setup
|
||||
uses: ./.github/actions/setup
|
||||
@@ -146,70 +124,84 @@ jobs:
|
||||
- name: Build and push TensorRT (x86 GPU)
|
||||
env:
|
||||
COMPUTE_LEVEL: "50 60 70 80 90"
|
||||
uses: docker/bake-action@v4
|
||||
uses: docker/bake-action@v6
|
||||
with:
|
||||
source: .
|
||||
push: true
|
||||
targets: tensorrt
|
||||
files: docker/tensorrt/trt.hcl
|
||||
set: |
|
||||
tensorrt.tags=${{ steps.setup.outputs.image-name }}-tensorrt
|
||||
*.cache-from=type=registry,ref=${{ steps.setup.outputs.cache-name }}-amd64
|
||||
*.cache-to=type=registry,ref=${{ steps.setup.outputs.cache-name }}-amd64,mode=max
|
||||
#- name: AMD/ROCm general build
|
||||
# env:
|
||||
# AMDGPU: gfx
|
||||
# HSA_OVERRIDE: 0
|
||||
# uses: docker/bake-action@v3
|
||||
# with:
|
||||
# push: true
|
||||
# targets: rocm
|
||||
# files: docker/rocm/rocm.hcl
|
||||
# set: |
|
||||
# rocm.tags=${{ steps.setup.outputs.image-name }}-rocm
|
||||
# *.cache-from=type=gha
|
||||
#- name: AMD/ROCm gfx900
|
||||
# env:
|
||||
# AMDGPU: gfx900
|
||||
# HSA_OVERRIDE: 1
|
||||
# HSA_OVERRIDE_GFX_VERSION: 9.0.0
|
||||
# uses: docker/bake-action@v3
|
||||
# with:
|
||||
# push: true
|
||||
# targets: rocm
|
||||
# files: docker/rocm/rocm.hcl
|
||||
# set: |
|
||||
# rocm.tags=${{ steps.setup.outputs.image-name }}-rocm-gfx900
|
||||
# *.cache-from=type=gha
|
||||
#- name: AMD/ROCm gfx1030
|
||||
# env:
|
||||
# AMDGPU: gfx1030
|
||||
# HSA_OVERRIDE: 1
|
||||
# HSA_OVERRIDE_GFX_VERSION: 10.3.0
|
||||
# uses: docker/bake-action@v3
|
||||
# with:
|
||||
# push: true
|
||||
# targets: rocm
|
||||
# files: docker/rocm/rocm.hcl
|
||||
# set: |
|
||||
# rocm.tags=${{ steps.setup.outputs.image-name }}-rocm-gfx1030
|
||||
# *.cache-from=type=gha
|
||||
#- name: AMD/ROCm gfx1100
|
||||
# env:
|
||||
# AMDGPU: gfx1100
|
||||
# HSA_OVERRIDE: 1
|
||||
# HSA_OVERRIDE_GFX_VERSION: 11.0.0
|
||||
# uses: docker/bake-action@v3
|
||||
# with:
|
||||
# push: true
|
||||
# targets: rocm
|
||||
# files: docker/rocm/rocm.hcl
|
||||
# set: |
|
||||
# rocm.tags=${{ steps.setup.outputs.image-name }}-rocm-gfx1100
|
||||
# *.cache-from=type=gha
|
||||
*.cache-from=type=registry,ref=${{ steps.setup.outputs.cache-name }}-tensorrt
|
||||
*.cache-to=type=registry,ref=${{ steps.setup.outputs.cache-name }}-tensorrt,mode=max
|
||||
- name: AMD/ROCm general build
|
||||
env:
|
||||
AMDGPU: gfx
|
||||
HSA_OVERRIDE: 0
|
||||
uses: docker/bake-action@v6
|
||||
with:
|
||||
source: .
|
||||
push: true
|
||||
targets: rocm
|
||||
files: docker/rocm/rocm.hcl
|
||||
set: |
|
||||
rocm.tags=${{ steps.setup.outputs.image-name }}-rocm
|
||||
*.cache-to=type=registry,ref=${{ steps.setup.outputs.cache-name }}-rocm,mode=max
|
||||
*.cache-from=type=registry,ref=${{ steps.setup.outputs.cache-name }}-rocm
|
||||
arm64_extra_builds:
|
||||
runs-on: ubuntu-22.04-arm
|
||||
name: ARM Extra Build
|
||||
needs:
|
||||
- arm64_build
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up QEMU and Buildx
|
||||
id: setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push Rockchip build
|
||||
uses: docker/bake-action@v6
|
||||
with:
|
||||
source: .
|
||||
push: true
|
||||
targets: rk
|
||||
files: docker/rockchip/rk.hcl
|
||||
set: |
|
||||
rk.tags=${{ steps.setup.outputs.image-name }}-rk
|
||||
*.cache-from=type=gha
|
||||
synaptics_build:
|
||||
runs-on: ubuntu-22.04-arm
|
||||
name: Synaptics Build
|
||||
needs:
|
||||
- arm64_build
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up QEMU and Buildx
|
||||
id: setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push Synaptics build
|
||||
uses: docker/bake-action@v6
|
||||
with:
|
||||
source: .
|
||||
push: true
|
||||
targets: synaptics
|
||||
files: docker/synaptics/synaptics.hcl
|
||||
set: |
|
||||
synaptics.tags=${{ steps.setup.outputs.image-name }}-synaptics
|
||||
*.cache-from=type=gha
|
||||
# The majority of users running arm64 are rpi users, so the rpi
|
||||
# build should be the primary arm64 image
|
||||
assemble_default_build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
name: Assemble and push default build
|
||||
needs:
|
||||
- amd64_build
|
||||
@@ -220,7 +212,7 @@ jobs:
|
||||
with:
|
||||
string: ${{ github.repository }}
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
@@ -229,7 +221,7 @@ jobs:
|
||||
run: echo "SHORT_SHA=${GITHUB_SHA::7}" >> $GITHUB_ENV
|
||||
- uses: int128/docker-manifest-create-action@v2
|
||||
with:
|
||||
tags: ghcr.io/${{ steps.lowercaseRepo.outputs.lowercase }}:${{ github.ref_name }}-${{ env.SHORT_SHA }}
|
||||
tags: ghcr.io/${{ steps.lowercaseRepo.outputs.lowercase }}:${{ env.SHORT_SHA }}
|
||||
sources: |
|
||||
ghcr.io/${{ steps.lowercaseRepo.outputs.lowercase }}:${{ github.ref_name }}-${{ env.SHORT_SHA }}-amd64
|
||||
ghcr.io/${{ steps.lowercaseRepo.outputs.lowercase }}:${{ github.ref_name }}-${{ env.SHORT_SHA }}-rpi
|
||||
ghcr.io/${{ steps.lowercaseRepo.outputs.lowercase }}:${{ env.SHORT_SHA }}-amd64
|
||||
ghcr.io/${{ steps.lowercaseRepo.outputs.lowercase }}:${{ env.SHORT_SHA }}-rpi
|
||||
|
24
.github/workflows/dependabot-auto-merge.yaml
vendored
@@ -1,24 +0,0 @@
|
||||
name: dependabot-auto-merge
|
||||
on: pull_request
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
dependabot-auto-merge:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.actor == 'dependabot[bot]'
|
||||
steps:
|
||||
- name: Get Dependabot metadata
|
||||
id: metadata
|
||||
uses: dependabot/fetch-metadata@v2
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Enable auto-merge for Dependabot PRs
|
||||
if: steps.metadata.outputs.dependency-type == 'direct:development' && (steps.metadata.outputs.update-type == 'version-update:semver-minor' || steps.metadata.outputs.update-type == 'version-update:semver-patch')
|
||||
run: |
|
||||
gh pr review --approve "$PR_URL"
|
||||
gh pr merge --auto --squash "$PR_URL"
|
||||
env:
|
||||
PR_URL: ${{ github.event.pull_request.html_url }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
84
.github/workflows/pull_request.yml
vendored
@@ -1,40 +1,24 @@
|
||||
name: On pull request
|
||||
|
||||
on: pull_request
|
||||
on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- "docs/**"
|
||||
- ".github/*.yml"
|
||||
- ".github/DISCUSSION_TEMPLATE/**"
|
||||
- ".github/ISSUE_TEMPLATE/**"
|
||||
|
||||
env:
|
||||
DEFAULT_PYTHON: 3.9
|
||||
DEFAULT_PYTHON: 3.11
|
||||
|
||||
jobs:
|
||||
build_devcontainer:
|
||||
runs-on: ubuntu-latest
|
||||
name: Build Devcontainer
|
||||
# The Dockerfile contains features that requires buildkit, and since the
|
||||
# devcontainer cli uses docker-compose to build the image, the only way to
|
||||
# ensure docker-compose uses buildkit is to explicitly enable it.
|
||||
env:
|
||||
DOCKER_BUILDKIT: "1"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@master
|
||||
with:
|
||||
node-version: 16.x
|
||||
- name: Install devcontainer cli
|
||||
run: npm install --global @devcontainers/cli
|
||||
- name: Build devcontainer
|
||||
run: devcontainer build --workspace-folder .
|
||||
# It would be nice to also test the following commands, but for some
|
||||
# reason they don't work even though in VS Code devcontainer works.
|
||||
# - name: Start devcontainer
|
||||
# run: devcontainer up --workspace-folder .
|
||||
# - name: Run devcontainer scripts
|
||||
# run: devcontainer run-user-commands --workspace-folder .
|
||||
|
||||
web_lint:
|
||||
name: Web - Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-node@master
|
||||
with:
|
||||
node-version: 16.x
|
||||
@@ -48,12 +32,17 @@ jobs:
|
||||
name: Web - Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-node@master
|
||||
with:
|
||||
node-version: 20.x
|
||||
- run: npm install
|
||||
working-directory: ./web
|
||||
- name: Build web
|
||||
run: npm run build
|
||||
working-directory: ./web
|
||||
# - name: Test
|
||||
# run: npm run test
|
||||
# working-directory: ./web
|
||||
@@ -63,9 +52,11 @@ jobs:
|
||||
name: Python Checks
|
||||
steps:
|
||||
- name: Check out the repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v5.1.0
|
||||
uses: actions/setup-python@v5.4.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
- name: Install requirements
|
||||
@@ -84,22 +75,21 @@ jobs:
|
||||
name: Python Tests
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-node@master
|
||||
with:
|
||||
node-version: 16.x
|
||||
- run: npm install
|
||||
working-directory: ./web
|
||||
- name: Build web
|
||||
run: npm run build
|
||||
working-directory: ./web
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Build
|
||||
run: make
|
||||
- name: Run mypy
|
||||
run: docker run --rm --entrypoint=python3 frigate:latest -u -m mypy --config-file frigate/mypy.ini frigate
|
||||
- name: Run tests
|
||||
run: docker run --rm --entrypoint=python3 frigate:latest -u -m unittest
|
||||
node-version: 20.x
|
||||
- name: Install devcontainer cli
|
||||
run: npm install --global @devcontainers/cli
|
||||
- name: Build devcontainer
|
||||
env:
|
||||
DOCKER_BUILDKIT: "1"
|
||||
run: devcontainer build --workspace-folder .
|
||||
- name: Start devcontainer
|
||||
run: devcontainer up --workspace-folder .
|
||||
- name: Run mypy in devcontainer
|
||||
run: devcontainer exec --workspace-folder . bash -lc "python3 -u -m mypy --config-file frigate/mypy.ini frigate"
|
||||
- name: Run unit tests in devcontainer
|
||||
run: devcontainer exec --workspace-folder . bash -lc "python3 -u -m unittest"
|
||||
|
23
.github/workflows/release.yml
vendored
@@ -10,23 +10,28 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- id: lowercaseRepo
|
||||
uses: ASzc/change-string-case-action@v6
|
||||
with:
|
||||
string: ${{ github.repository }}
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Create tag variables
|
||||
env:
|
||||
TAG: ${{ github.ref_name }}
|
||||
LOWERCASE_REPO: ${{ steps.lowercaseRepo.outputs.lowercase }}
|
||||
run: |
|
||||
BRANCH=$([[ "${{ github.ref_name }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] && echo "master" || echo "dev")
|
||||
echo "BRANCH=${BRANCH}" >> $GITHUB_ENV
|
||||
echo "BASE=ghcr.io/${{ steps.lowercaseRepo.outputs.lowercase }}" >> $GITHUB_ENV
|
||||
echo "BUILD_TAG=${BRANCH}-${GITHUB_SHA::7}" >> $GITHUB_ENV
|
||||
BUILD_TYPE=$([[ "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] && echo "stable" || echo "beta")
|
||||
echo "BUILD_TYPE=${BUILD_TYPE}" >> $GITHUB_ENV
|
||||
echo "BASE=ghcr.io/${LOWERCASE_REPO}" >> $GITHUB_ENV
|
||||
echo "BUILD_TAG=${GITHUB_SHA::7}" >> $GITHUB_ENV
|
||||
echo "CLEAN_VERSION=$(echo ${GITHUB_REF##*/} | tr '[:upper:]' '[:lower:]' | sed 's/^[v]//')" >> $GITHUB_ENV
|
||||
- name: Tag and push the main image
|
||||
run: |
|
||||
@@ -34,14 +39,14 @@ jobs:
|
||||
STABLE_TAG=${BASE}:stable
|
||||
PULL_TAG=${BASE}:${BUILD_TAG}
|
||||
docker run --rm -v $HOME/.docker/config.json:/config.json quay.io/skopeo/stable:latest copy --authfile /config.json --multi-arch all docker://${PULL_TAG} docker://${VERSION_TAG}
|
||||
for variant in standard-arm64 tensorrt tensorrt-jp4 tensorrt-jp5 rk; do
|
||||
for variant in standard-arm64 tensorrt tensorrt-jp6 rk rocm; do
|
||||
docker run --rm -v $HOME/.docker/config.json:/config.json quay.io/skopeo/stable:latest copy --authfile /config.json --multi-arch all docker://${PULL_TAG}-${variant} docker://${VERSION_TAG}-${variant}
|
||||
done
|
||||
|
||||
# stable tag
|
||||
if [[ "${BRANCH}" == "master" ]]; then
|
||||
if [[ "${BUILD_TYPE}" == "stable" ]]; then
|
||||
docker run --rm -v $HOME/.docker/config.json:/config.json quay.io/skopeo/stable:latest copy --authfile /config.json --multi-arch all docker://${PULL_TAG} docker://${STABLE_TAG}
|
||||
for variant in standard-arm64 tensorrt tensorrt-jp4 tensorrt-jp5 rk; do
|
||||
for variant in standard-arm64 tensorrt tensorrt-jp6 rk rocm; do
|
||||
docker run --rm -v $HOME/.docker/config.json:/config.json quay.io/skopeo/stable:latest copy --authfile /config.json --multi-arch all docker://${PULL_TAG}-${variant} docker://${STABLE_TAG}-${variant}
|
||||
done
|
||||
fi
|
||||
|
31
.github/workflows/stale.yml
vendored
@@ -23,19 +23,20 @@ jobs:
|
||||
exempt-pr-labels: "pinned,security,dependencies"
|
||||
operations-per-run: 120
|
||||
- name: Print outputs
|
||||
run: echo ${{ join(steps.stale.outputs.*, ',') }}
|
||||
|
||||
clean_ghcr:
|
||||
name: Delete outdated dev container images
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Delete old images
|
||||
uses: snok/container-retention-policy@v2
|
||||
with:
|
||||
image-names: dev-*
|
||||
cut-off: 60 days ago UTC
|
||||
keep-at-least: 5
|
||||
account-type: personal
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
token-type: github-token
|
||||
env:
|
||||
STALE_OUTPUT: ${{ join(steps.stale.outputs.*, ',') }}
|
||||
run: echo "$STALE_OUTPUT"
|
||||
|
||||
# clean_ghcr:
|
||||
# name: Delete outdated dev container images
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - name: Delete old images
|
||||
# uses: snok/container-retention-policy@v2
|
||||
# with:
|
||||
# image-names: dev-*
|
||||
# cut-off: 60 days ago UTC
|
||||
# keep-at-least: 5
|
||||
# account-type: personal
|
||||
# token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# token-type: github-token
|
||||
|
3
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
.DS_Store
|
||||
*.pyc
|
||||
__pycache__
|
||||
.mypy_cache
|
||||
*.swp
|
||||
debug
|
||||
.vscode/*
|
||||
|
5
.vscode/launch.json
vendored
@@ -3,10 +3,9 @@
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Python: Launch Frigate",
|
||||
"type": "python",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"module": "frigate",
|
||||
"justMyCode": true
|
||||
"module": "frigate"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -4,3 +4,4 @@
|
||||
/docker/tensorrt/*jetson* @madsciencetist
|
||||
/docker/rockchip/ @MarcA711
|
||||
/docker/rocm/ @harakas
|
||||
/docker/hailo8l/ @spanner3003
|
||||
|
37
Makefile
@@ -1,11 +1,9 @@
|
||||
default_target: local
|
||||
|
||||
COMMIT_HASH := $(shell git log -1 --pretty=format:"%h"|tail -1)
|
||||
VERSION = 0.14.0
|
||||
VERSION = 0.17.0
|
||||
IMAGE_REPO ?= ghcr.io/blakeblackshear/frigate
|
||||
GITHUB_REF_NAME ?= $(shell git rev-parse --abbrev-ref HEAD)
|
||||
CURRENT_UID := $(shell id -u)
|
||||
CURRENT_GID := $(shell id -g)
|
||||
BOARDS= #Initialized empty
|
||||
|
||||
include docker/*/*.mk
|
||||
@@ -18,25 +16,44 @@ version:
|
||||
echo 'VERSION = "$(VERSION)-$(COMMIT_HASH)"' > frigate/version.py
|
||||
|
||||
local: version
|
||||
docker buildx build --target=frigate --tag frigate:latest --load --file docker/main/Dockerfile .
|
||||
docker buildx build --target=frigate --file docker/main/Dockerfile . \
|
||||
--tag frigate:latest \
|
||||
--load
|
||||
|
||||
debug: version
|
||||
docker buildx build --target=frigate --file docker/main/Dockerfile . \
|
||||
--build-arg DEBUG=true \
|
||||
--tag frigate:latest \
|
||||
--load
|
||||
|
||||
amd64:
|
||||
docker buildx build --platform linux/amd64 --target=frigate --tag $(IMAGE_REPO):$(VERSION)-$(COMMIT_HASH) --file docker/main/Dockerfile .
|
||||
docker buildx build --target=frigate --file docker/main/Dockerfile . \
|
||||
--tag $(IMAGE_REPO):$(VERSION)-$(COMMIT_HASH) \
|
||||
--platform linux/amd64
|
||||
|
||||
arm64:
|
||||
docker buildx build --platform linux/arm64 --target=frigate --tag $(IMAGE_REPO):$(VERSION)-$(COMMIT_HASH) --file docker/main/Dockerfile .
|
||||
docker buildx build --target=frigate --file docker/main/Dockerfile . \
|
||||
--tag $(IMAGE_REPO):$(VERSION)-$(COMMIT_HASH) \
|
||||
--platform linux/arm64
|
||||
|
||||
build: version amd64 arm64
|
||||
docker buildx build --platform linux/arm64/v8,linux/amd64 --target=frigate --tag $(IMAGE_REPO):$(VERSION)-$(COMMIT_HASH) --file docker/main/Dockerfile .
|
||||
docker buildx build --target=frigate --file docker/main/Dockerfile . \
|
||||
--tag $(IMAGE_REPO):$(VERSION)-$(COMMIT_HASH) \
|
||||
--platform linux/arm64/v8,linux/amd64
|
||||
|
||||
push: push-boards
|
||||
docker buildx build --push --platform linux/arm64/v8,linux/amd64 --target=frigate --tag $(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH) --file docker/main/Dockerfile .
|
||||
docker buildx build --target=frigate --file docker/main/Dockerfile . \
|
||||
--tag $(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH) \
|
||||
--platform linux/arm64/v8,linux/amd64 \
|
||||
--push
|
||||
|
||||
run: local
|
||||
docker run --rm --publish=5000:5000 --volume=${PWD}/config:/config frigate:latest
|
||||
|
||||
run_tests: local
|
||||
docker run --rm --workdir=/opt/frigate --entrypoint= frigate:latest python3 -u -m unittest
|
||||
docker run --rm --workdir=/opt/frigate --entrypoint= frigate:latest python3 -u -m mypy --config-file frigate/mypy.ini frigate
|
||||
docker run --rm --workdir=/opt/frigate --entrypoint= frigate:latest \
|
||||
python3 -u -m unittest
|
||||
docker run --rm --workdir=/opt/frigate --entrypoint= frigate:latest \
|
||||
python3 -u -m mypy --config-file frigate/mypy.ini frigate
|
||||
|
||||
.PHONY: run_tests
|
||||
|
38
README.md
@@ -4,9 +4,15 @@
|
||||
|
||||
# Frigate - NVR With Realtime Object Detection for IP Cameras
|
||||
|
||||
<a href="https://hosted.weblate.org/engage/frigate-nvr/">
|
||||
<img src="https://hosted.weblate.org/widget/frigate-nvr/language-badge.svg" alt="Translation status" />
|
||||
</a>
|
||||
|
||||
\[English\] | [简体中文](https://github.com/blakeblackshear/frigate/blob/dev/README_CN.md)
|
||||
|
||||
A complete and local NVR designed for [Home Assistant](https://www.home-assistant.io) with AI object detection. Uses OpenCV and Tensorflow to perform realtime object detection locally for IP cameras.
|
||||
|
||||
Use of a [Google Coral Accelerator](https://coral.ai/products/) is optional, but highly recommended. The Coral will outperform even the best CPUs and can process 100+ FPS with very little overhead.
|
||||
Use of a GPU or AI accelerator such as a [Google Coral](https://coral.ai/products/) or [Hailo](https://hailo.ai/) is highly recommended. AI accelerators will outperform even the best CPUs with very little overhead.
|
||||
|
||||
- Tight integration with Home Assistant via a [custom component](https://github.com/blakeblackshear/frigate-hass-integration)
|
||||
- Designed to minimize resource use and maximize performance by only looking for objects when and where it is necessary
|
||||
@@ -29,18 +35,34 @@ If you would like to make a donation to support development, please use [Github
|
||||
|
||||
## Screenshots
|
||||
|
||||
Integration into Home Assistant
|
||||
### Live dashboard
|
||||
|
||||
<div>
|
||||
<a href="docs/static/img/media_browser.png"><img src="docs/static/img/media_browser.png" height=400></a>
|
||||
<a href="docs/static/img/notification.png"><img src="docs/static/img/notification.png" height=400></a>
|
||||
<img width="800" alt="Live dashboard" src="https://github.com/blakeblackshear/frigate/assets/569905/5e713cb9-9db5-41dc-947a-6937c3bc376e">
|
||||
</div>
|
||||
|
||||
Also comes with a builtin UI:
|
||||
### Streamlined review workflow
|
||||
|
||||
<div>
|
||||
<a href="docs/static/img/home-ui.png"><img src="docs/static/img/home-ui.png" height=400></a>
|
||||
<a href="docs/static/img/camera-ui.png"><img src="docs/static/img/camera-ui.png" height=400></a>
|
||||
<img width="800" alt="Streamlined review workflow" src="https://github.com/blakeblackshear/frigate/assets/569905/6fed96e8-3b18-40e5-9ddc-31e6f3c9f2ff">
|
||||
</div>
|
||||
|
||||

|
||||
### Multi-camera scrubbing
|
||||
|
||||
<div>
|
||||
<img width="800" alt="Multi-camera scrubbing" src="https://github.com/blakeblackshear/frigate/assets/569905/d6788a15-0eeb-4427-a8d4-80b93cae3d74">
|
||||
</div>
|
||||
|
||||
### Built-in mask and zone editor
|
||||
|
||||
<div>
|
||||
<img width="800" alt="Multi-camera scrubbing" src="https://github.com/blakeblackshear/frigate/assets/569905/d7885fc3-bfe6-452f-b7d0-d957cb3e31f5">
|
||||
</div>
|
||||
|
||||
## Translations
|
||||
|
||||
We use [Weblate](https://hosted.weblate.org/projects/frigate-nvr/) to support language translations. Contributions are always welcome.
|
||||
|
||||
<a href="https://hosted.weblate.org/engage/frigate-nvr/">
|
||||
<img src="https://hosted.weblate.org/widget/frigate-nvr/multi-auto.svg" alt="Translation status" />
|
||||
</a>
|
||||
|
70
README_CN.md
Normal file
@@ -0,0 +1,70 @@
|
||||
<p align="center">
|
||||
<img align="center" alt="logo" src="docs/static/img/frigate.png">
|
||||
</p>
|
||||
|
||||
# Frigate - 一个具有实时目标检测的本地NVR
|
||||
|
||||
[English](https://github.com/blakeblackshear/frigate) | \[简体中文\]
|
||||
|
||||
<a href="https://hosted.weblate.org/engage/frigate-nvr/-/zh_Hans/">
|
||||
<img src="https://hosted.weblate.org/widget/frigate-nvr/-/zh_Hans/svg-badge.svg" alt="翻译状态" />
|
||||
</a>
|
||||
|
||||
一个完整的本地网络视频录像机(NVR),专为[Home Assistant](https://www.home-assistant.io)设计,具备AI物体检测功能。使用OpenCV和TensorFlow在本地为IP摄像头执行实时物体检测。
|
||||
|
||||
强烈推荐使用GPU或者AI加速器(例如[Google Coral加速器](https://coral.ai/products/) 或者 [Hailo](https://hailo.ai/))。它们的性能甚至超过目前的顶级CPU,并且可以以极低的耗电实现更优的性能。
|
||||
- 通过[自定义组件](https://github.com/blakeblackshear/frigate-hass-integration)与Home Assistant紧密集成
|
||||
- 设计上通过仅在必要时和必要地点寻找物体,最大限度地减少资源使用并最大化性能
|
||||
- 大量利用多进程处理,强调实时性而非处理每一帧
|
||||
- 使用非常低开销的运动检测来确定运行物体检测的位置
|
||||
- 使用TensorFlow进行物体检测,运行在单独的进程中以达到最大FPS
|
||||
- 通过MQTT进行通信,便于集成到其他系统中
|
||||
- 根据检测到的物体设置保留时间进行视频录制
|
||||
- 24/7全天候录制
|
||||
- 通过RTSP重新流传输以减少摄像头的连接数
|
||||
- 支持WebRTC和MSE,实现低延迟的实时观看
|
||||
|
||||
## 社区中文翻译文档
|
||||
|
||||
你可以在这里查看文档 https://docs.frigate-cn.video
|
||||
|
||||
## 赞助
|
||||
|
||||
如果您想通过捐赠支持开发,请使用 [Github Sponsors](https://github.com/sponsors/blakeblackshear)。
|
||||
|
||||
## 截图
|
||||
|
||||
### 实时监控面板
|
||||
<div>
|
||||
<img width="800" alt="实时监控面板" src="https://github.com/blakeblackshear/frigate/assets/569905/5e713cb9-9db5-41dc-947a-6937c3bc376e">
|
||||
</div>
|
||||
|
||||
### 简单的核查工作流程
|
||||
<div>
|
||||
<img width="800" alt="简单的审查工作流程" src="https://github.com/blakeblackshear/frigate/assets/569905/6fed96e8-3b18-40e5-9ddc-31e6f3c9f2ff">
|
||||
</div>
|
||||
|
||||
### 多摄像头可按时间轴查看
|
||||
<div>
|
||||
<img width="800" alt="多摄像头可按时间轴查看" src="https://github.com/blakeblackshear/frigate/assets/569905/d6788a15-0eeb-4427-a8d4-80b93cae3d74">
|
||||
</div>
|
||||
|
||||
### 内置遮罩和区域编辑器
|
||||
<div>
|
||||
<img width="800" alt="内置遮罩和区域编辑器" src="https://github.com/blakeblackshear/frigate/assets/569905/d7885fc3-bfe6-452f-b7d0-d957cb3e31f5">
|
||||
</div>
|
||||
|
||||
|
||||
## 翻译
|
||||
我们使用 [Weblate](https://hosted.weblate.org/projects/frigate-nvr/) 平台提供翻译支持,欢迎参与进来一起完善。
|
||||
|
||||
|
||||
## 非官方中文讨论社区
|
||||
欢迎加入中文讨论QQ群:[1043861059](https://qm.qq.com/q/7vQKsTmSz)
|
||||
|
||||
Bilibili:https://space.bilibili.com/3546894915602564
|
||||
|
||||
|
||||
## 中文社区赞助商
|
||||
[](https://edgeone.ai/zh?from=github)
|
||||
本项目 CDN 加速及安全防护由 Tencent EdgeOne 赞助
|
@@ -5,11 +5,12 @@ from statistics import mean
|
||||
import numpy as np
|
||||
|
||||
from frigate.config import DetectorTypeEnum
|
||||
from frigate.object_detection import (
|
||||
from frigate.object_detection.base import (
|
||||
ObjectDetectProcess,
|
||||
RemoteObjectDetector,
|
||||
load_labels,
|
||||
)
|
||||
from frigate.util.process import FrigateProcess
|
||||
|
||||
my_frame = np.expand_dims(np.full((300, 300, 3), 1, np.uint8), axis=0)
|
||||
labels = load_labels("/labelmap.txt")
|
||||
@@ -60,7 +61,7 @@ def start(id, num_detections, detection_queue, event):
|
||||
object_detector.cleanup()
|
||||
print(f"{id} - Processed for {duration:.2f} seconds.")
|
||||
print(f"{id} - FPS: {object_detector.fps.eps():.2f}")
|
||||
print(f"{id} - Average frame processing time: {mean(frame_times)*1000:.2f}ms")
|
||||
print(f"{id} - Average frame processing time: {mean(frame_times) * 1000:.2f}ms")
|
||||
|
||||
|
||||
######
|
||||
@@ -90,7 +91,7 @@ edgetpu_process_2 = ObjectDetectProcess(
|
||||
)
|
||||
|
||||
for x in range(0, 10):
|
||||
camera_process = mp.Process(
|
||||
camera_process = FrigateProcess(
|
||||
target=start, args=(x, 300, detection_queue, events[str(x)])
|
||||
)
|
||||
camera_process.daemon = True
|
||||
|
@@ -7,7 +7,8 @@
|
||||
"*.db",
|
||||
"node_modules",
|
||||
"__pycache__",
|
||||
"dist"
|
||||
"dist",
|
||||
"/audio-labelmap.txt"
|
||||
],
|
||||
"language": "en",
|
||||
"dictionaryDefinitions": [
|
||||
|
@@ -1,8 +1,8 @@
|
||||
version: "3"
|
||||
services:
|
||||
devcontainer:
|
||||
container_name: frigate-devcontainer
|
||||
# add groups from host for render, plugdev, video
|
||||
# Check host system's actual render/video/plugdev group IDs with 'getent group render', 'getent group video', and 'getent group plugdev'
|
||||
# Must add these exact IDs in container's group_add section or OpenVINO GPU acceleration will fail
|
||||
group_add:
|
||||
- "109" # render
|
||||
- "110" # render
|
||||
@@ -23,9 +23,9 @@ services:
|
||||
# count: 1
|
||||
# capabilities: [gpu]
|
||||
environment:
|
||||
YOLO_MODELS: yolov7-320
|
||||
devices:
|
||||
- /dev/bus/usb:/dev/bus/usb
|
||||
YOLO_MODELS: ""
|
||||
# devices:
|
||||
# - /dev/bus/usb:/dev/bus/usb # Uncomment for Google Coral USB
|
||||
# - /dev/dri:/dev/dri # for intel hwaccel, needs to be updated for your hardware
|
||||
volumes:
|
||||
- .:/workspace/frigate:cached
|
||||
@@ -33,9 +33,10 @@ services:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- ./config:/config
|
||||
- ./debug:/media/frigate
|
||||
- /dev/bus/usb:/dev/bus/usb
|
||||
# - /dev/bus/usb:/dev/bus/usb # Uncomment for Google Coral USB
|
||||
mqtt:
|
||||
container_name: mqtt
|
||||
image: eclipse-mosquitto:1.6
|
||||
image: eclipse-mosquitto:2.0
|
||||
command: mosquitto -c /mosquitto-no-auth.conf # enable no-auth mode
|
||||
ports:
|
||||
- "1883:1883"
|
||||
|
49
docker/hailo8l/user_installation.sh
Normal file
@@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Update package list and install dependencies
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential cmake git wget
|
||||
|
||||
hailo_version="4.21.0"
|
||||
arch=$(uname -m)
|
||||
|
||||
if [[ $arch == "x86_64" ]]; then
|
||||
sudo apt install -y linux-headers-$(uname -r);
|
||||
else
|
||||
sudo apt install -y linux-modules-extra-$(uname -r);
|
||||
fi
|
||||
|
||||
# Clone the HailoRT driver repository
|
||||
git clone --depth 1 --branch v${hailo_version} https://github.com/hailo-ai/hailort-drivers.git
|
||||
|
||||
# Build and install the HailoRT driver
|
||||
cd hailort-drivers/linux/pcie
|
||||
sudo make all
|
||||
sudo make install
|
||||
|
||||
# Load the Hailo PCI driver
|
||||
sudo modprobe hailo_pci
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Unable to load hailo_pci module, common reasons for this are:"
|
||||
echo "- Key was rejected by service: Secure Boot is enabling disallowing install."
|
||||
echo "- Permissions are not setup correctly."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Download and install the firmware
|
||||
cd ../../
|
||||
./download_firmware.sh
|
||||
|
||||
# verify the firmware folder is present
|
||||
if [ ! -d /lib/firmware/hailo ]; then
|
||||
sudo mkdir /lib/firmware/hailo
|
||||
fi
|
||||
sudo mv hailo8_fw.*.bin /lib/firmware/hailo/hailo8_fw.bin
|
||||
|
||||
# Install udev rules
|
||||
sudo cp ./linux/pcie/51-hailo-udev.rules /etc/udev/rules.d/
|
||||
sudo udevadm control --reload-rules && sudo udevadm trigger
|
||||
|
||||
echo "HailoRT driver installation complete."
|
||||
echo "reboot your system to load the firmware!"
|
@@ -3,14 +3,29 @@
|
||||
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ARG BASE_IMAGE=debian:11
|
||||
ARG SLIM_BASE=debian:11-slim
|
||||
# Globally set pip break-system-packages option to avoid having to specify it every time
|
||||
ARG PIP_BREAK_SYSTEM_PACKAGES=1
|
||||
|
||||
ARG BASE_IMAGE=debian:12
|
||||
ARG SLIM_BASE=debian:12-slim
|
||||
|
||||
# A hook that allows us to inject commands right after the base images
|
||||
ARG BASE_HOOK=
|
||||
|
||||
FROM ${BASE_IMAGE} AS base
|
||||
ARG PIP_BREAK_SYSTEM_PACKAGES
|
||||
ARG BASE_HOOK
|
||||
|
||||
FROM --platform=${BUILDPLATFORM} debian:11 AS base_host
|
||||
RUN sh -c "$BASE_HOOK"
|
||||
|
||||
FROM --platform=${BUILDPLATFORM} debian:12 AS base_host
|
||||
ARG PIP_BREAK_SYSTEM_PACKAGES
|
||||
|
||||
FROM ${SLIM_BASE} AS slim-base
|
||||
ARG PIP_BREAK_SYSTEM_PACKAGES
|
||||
ARG BASE_HOOK
|
||||
|
||||
RUN sh -c "$BASE_HOOK"
|
||||
|
||||
FROM slim-base AS wget
|
||||
ARG DEBIAN_FRONTEND
|
||||
@@ -24,17 +39,28 @@ ARG DEBIAN_FRONTEND
|
||||
ENV CCACHE_DIR /root/.ccache
|
||||
ENV CCACHE_MAXSIZE 2G
|
||||
|
||||
# bind /var/cache/apt to tmpfs to speed up nginx build
|
||||
RUN --mount=type=tmpfs,target=/tmp --mount=type=tmpfs,target=/var/cache/apt \
|
||||
--mount=type=bind,source=docker/main/build_nginx.sh,target=/deps/build_nginx.sh \
|
||||
--mount=type=cache,target=/root/.ccache \
|
||||
RUN --mount=type=bind,source=docker/main/build_nginx.sh,target=/deps/build_nginx.sh \
|
||||
/deps/build_nginx.sh
|
||||
|
||||
FROM wget AS sqlite-vec
|
||||
ARG DEBIAN_FRONTEND
|
||||
|
||||
# Build sqlite_vec from source
|
||||
COPY docker/main/build_sqlite_vec.sh /deps/build_sqlite_vec.sh
|
||||
RUN --mount=type=tmpfs,target=/tmp --mount=type=tmpfs,target=/var/cache/apt \
|
||||
--mount=type=bind,source=docker/main/build_sqlite_vec.sh,target=/deps/build_sqlite_vec.sh \
|
||||
--mount=type=cache,target=/root/.ccache \
|
||||
/deps/build_sqlite_vec.sh
|
||||
|
||||
FROM scratch AS go2rtc
|
||||
ARG TARGETARCH
|
||||
WORKDIR /rootfs/usr/local/go2rtc/bin
|
||||
ADD --link --chmod=755 "https://github.com/AlexxIT/go2rtc/releases/download/v1.9.2/go2rtc_linux_${TARGETARCH}" go2rtc
|
||||
ADD --link --chmod=755 "https://github.com/AlexxIT/go2rtc/releases/download/v1.9.10/go2rtc_linux_${TARGETARCH}" go2rtc
|
||||
|
||||
FROM wget AS tempio
|
||||
ARG TARGETARCH
|
||||
RUN --mount=type=bind,source=docker/main/install_tempio.sh,target=/deps/install_tempio.sh \
|
||||
/deps/install_tempio.sh
|
||||
|
||||
####
|
||||
#
|
||||
@@ -52,8 +78,9 @@ COPY docker/main/requirements-ov.txt /requirements-ov.txt
|
||||
RUN apt-get -qq update \
|
||||
&& apt-get -qq install -y wget python3 python3-dev python3-distutils gcc pkg-config libhdf5-dev \
|
||||
&& wget -q https://bootstrap.pypa.io/get-pip.py -O get-pip.py \
|
||||
&& sed -i 's/args.append("setuptools")/args.append("setuptools==77.0.3")/' get-pip.py \
|
||||
&& python3 get-pip.py "pip" \
|
||||
&& pip install -r /requirements-ov.txt
|
||||
&& pip3 install -r /requirements-ov.txt
|
||||
|
||||
# Get OpenVino Model
|
||||
RUN --mount=type=bind,source=docker/main/build_ov_model.py,target=/build_ov_model.py \
|
||||
@@ -62,6 +89,40 @@ RUN --mount=type=bind,source=docker/main/build_ov_model.py,target=/build_ov_mode
|
||||
&& tar -xvf ssdlite_mobilenet_v2_coco_2018_05_09.tar.gz \
|
||||
&& python3 /build_ov_model.py
|
||||
|
||||
####
|
||||
#
|
||||
# Coral Compatibility
|
||||
#
|
||||
# Builds libusb without udev. Needed for synology and other devices with USB coral
|
||||
####
|
||||
# libUSB - No Udev
|
||||
FROM wget as libusb-build
|
||||
ARG TARGETARCH
|
||||
ARG DEBIAN_FRONTEND
|
||||
ENV CCACHE_DIR /root/.ccache
|
||||
ENV CCACHE_MAXSIZE 2G
|
||||
|
||||
# Build libUSB without udev. Needed for Openvino NCS2 support
|
||||
WORKDIR /opt
|
||||
RUN apt-get update && apt-get install -y unzip build-essential automake libtool ccache pkg-config
|
||||
RUN --mount=type=cache,target=/root/.ccache wget -q https://github.com/libusb/libusb/archive/v1.0.26.zip -O v1.0.26.zip && \
|
||||
unzip v1.0.26.zip && cd libusb-1.0.26 && \
|
||||
./bootstrap.sh && \
|
||||
./configure CC='ccache gcc' CCX='ccache g++' --disable-udev --enable-shared && \
|
||||
make -j $(nproc --all)
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends libusb-1.0-0-dev && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
WORKDIR /opt/libusb-1.0.26/libusb
|
||||
RUN /bin/mkdir -p '/usr/local/lib' && \
|
||||
/bin/bash ../libtool --mode=install /usr/bin/install -c libusb-1.0.la '/usr/local/lib' && \
|
||||
/bin/mkdir -p '/usr/local/include/libusb-1.0' && \
|
||||
/usr/bin/install -c -m 644 libusb.h '/usr/local/include/libusb-1.0' && \
|
||||
/bin/mkdir -p '/usr/local/lib/pkgconfig' && \
|
||||
cd /opt/libusb-1.0.26/ && \
|
||||
/usr/bin/install -c -m 644 libusb-1.0.pc '/usr/local/lib/pkgconfig' && \
|
||||
ldconfig
|
||||
|
||||
FROM wget AS models
|
||||
|
||||
# Get model and labels
|
||||
@@ -74,7 +135,7 @@ COPY --from=ov-converter /models/ssdlite_mobilenet_v2.bin openvino-model/
|
||||
RUN wget -q https://github.com/openvinotoolkit/open_model_zoo/raw/master/data/dataset_classes/coco_91cl_bkgr.txt -O openvino-model/coco_91cl_bkgr.txt && \
|
||||
sed -i 's/truck/car/g' openvino-model/coco_91cl_bkgr.txt
|
||||
# Get Audio Model and labels
|
||||
RUN wget -qO cpu_audio_model.tflite https://tfhub.dev/google/lite-model/yamnet/classification/tflite/1?lite-format=tflite
|
||||
RUN wget -qO - https://www.kaggle.com/api/v1/models/google/yamnet/tfLite/classification-tflite/1/download | tar xvz && mv 1.tflite cpu_audio_model.tflite
|
||||
COPY audio-labelmap.txt .
|
||||
|
||||
|
||||
@@ -87,58 +148,71 @@ RUN --mount=type=bind,source=docker/main/install_s6_overlay.sh,target=/deps/inst
|
||||
FROM base AS wheels
|
||||
ARG DEBIAN_FRONTEND
|
||||
ARG TARGETARCH
|
||||
ARG DEBUG=false
|
||||
|
||||
# Use a separate container to build wheels to prevent build dependencies in final image
|
||||
RUN apt-get -qq update \
|
||||
&& apt-get -qq install -y \
|
||||
apt-transport-https \
|
||||
gnupg \
|
||||
wget \
|
||||
# the key fingerprint can be obtained from https://ftp-master.debian.org/keys.html
|
||||
&& wget -qO- "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xA4285295FC7B1A81600062A9605C66F00D6C9793" | \
|
||||
gpg --dearmor > /usr/share/keyrings/debian-archive-bullseye-stable.gpg \
|
||||
&& echo "deb [signed-by=/usr/share/keyrings/debian-archive-bullseye-stable.gpg] http://deb.debian.org/debian bullseye main contrib non-free" | \
|
||||
tee /etc/apt/sources.list.d/debian-bullseye-nonfree.list \
|
||||
apt-transport-https wget unzip \
|
||||
&& apt-get -qq update \
|
||||
&& apt-get -qq install -y \
|
||||
python3.9 \
|
||||
python3.9-dev \
|
||||
python3.11 \
|
||||
python3.11-dev \
|
||||
# opencv dependencies
|
||||
build-essential cmake git pkg-config libgtk-3-dev \
|
||||
libavcodec-dev libavformat-dev libswscale-dev libv4l-dev \
|
||||
libxvidcore-dev libx264-dev libjpeg-dev libpng-dev libtiff-dev \
|
||||
gfortran openexr libatlas-base-dev libssl-dev\
|
||||
libtbb2 libtbb-dev libdc1394-22-dev libopenexr-dev \
|
||||
libtbbmalloc2 libtbb-dev libdc1394-dev libopenexr-dev \
|
||||
libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev \
|
||||
# sqlite3 dependencies
|
||||
tclsh \
|
||||
# scipy dependencies
|
||||
gcc gfortran libopenblas-dev liblapack-dev && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Ensure python3 defaults to python3.9
|
||||
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.9 1
|
||||
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1
|
||||
|
||||
RUN wget -q https://bootstrap.pypa.io/get-pip.py -O get-pip.py \
|
||||
&& sed -i 's/args.append("setuptools")/args.append("setuptools==77.0.3")/' get-pip.py \
|
||||
&& python3 get-pip.py "pip"
|
||||
|
||||
COPY docker/main/requirements.txt /requirements.txt
|
||||
COPY docker/main/requirements-dev.txt /requirements-dev.txt
|
||||
|
||||
RUN pip3 install -r /requirements.txt
|
||||
|
||||
COPY docker/main/requirements-wheels.txt /requirements-wheels.txt
|
||||
RUN pip3 wheel --wheel-dir=/wheels -r /requirements-wheels.txt
|
||||
# Build pysqlite3 from source
|
||||
COPY docker/main/build_pysqlite3.sh /build_pysqlite3.sh
|
||||
RUN /build_pysqlite3.sh
|
||||
|
||||
COPY docker/main/requirements-wheels.txt /requirements-wheels.txt
|
||||
RUN pip3 wheel --wheel-dir=/wheels -r /requirements-wheels.txt && \
|
||||
if [ "$DEBUG" = "true" ]; then \
|
||||
pip3 wheel --wheel-dir=/wheels -r /requirements-dev.txt; \
|
||||
fi
|
||||
|
||||
# Install HailoRT & Wheels
|
||||
RUN --mount=type=bind,source=docker/main/install_hailort.sh,target=/deps/install_hailort.sh \
|
||||
/deps/install_hailort.sh
|
||||
|
||||
# Collect deps in a single layer
|
||||
FROM scratch AS deps-rootfs
|
||||
COPY --from=nginx /usr/local/nginx/ /usr/local/nginx/
|
||||
COPY --from=sqlite-vec /usr/local/lib/ /usr/local/lib/
|
||||
COPY --from=go2rtc /rootfs/ /
|
||||
COPY --from=libusb-build /usr/local/lib /usr/local/lib
|
||||
COPY --from=tempio /rootfs/ /
|
||||
COPY --from=s6-overlay /rootfs/ /
|
||||
COPY --from=models /rootfs/ /
|
||||
COPY --from=wheels /rootfs/ /
|
||||
COPY docker/main/rootfs/ /
|
||||
|
||||
|
||||
# Frigate deps (ffmpeg, python, nginx, go2rtc, s6-overlay, etc)
|
||||
FROM slim-base AS deps
|
||||
ARG TARGETARCH
|
||||
ARG BASE_IMAGE
|
||||
|
||||
ARG DEBIAN_FRONTEND
|
||||
# http://stackoverflow.com/questions/48162574/ddg#49462622
|
||||
@@ -148,18 +222,48 @@ ARG APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
|
||||
ENV NVIDIA_VISIBLE_DEVICES=all
|
||||
ENV NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
|
||||
|
||||
ENV PATH="/usr/lib/btbn-ffmpeg/bin:/usr/local/go2rtc/bin:/usr/local/nginx/sbin:${PATH}"
|
||||
# Disable tokenizer parallelism warning
|
||||
# https://stackoverflow.com/questions/62691279/how-to-disable-tokenizers-parallelism-true-false-warning/72926996#72926996
|
||||
ENV TOKENIZERS_PARALLELISM=true
|
||||
# https://github.com/huggingface/transformers/issues/27214
|
||||
ENV TRANSFORMERS_NO_ADVISORY_WARNINGS=1
|
||||
|
||||
# Set OpenCV ffmpeg loglevel to fatal: https://ffmpeg.org/doxygen/trunk/log_8h.html
|
||||
ENV OPENCV_FFMPEG_LOGLEVEL=8
|
||||
|
||||
# Set NumPy to ignore getlimits warning
|
||||
ENV PYTHONWARNINGS="ignore:::numpy.core.getlimits"
|
||||
|
||||
# Set HailoRT to disable logging
|
||||
ENV HAILORT_LOGGER_PATH=NONE
|
||||
|
||||
# TensorFlow error only
|
||||
ENV TF_CPP_MIN_LOG_LEVEL=3
|
||||
|
||||
ENV PATH="/usr/local/go2rtc/bin:/usr/local/tempio/bin:/usr/local/nginx/sbin:${PATH}"
|
||||
|
||||
# Install dependencies
|
||||
RUN --mount=type=bind,source=docker/main/install_deps.sh,target=/deps/install_deps.sh \
|
||||
/deps/install_deps.sh
|
||||
|
||||
ENV DEFAULT_FFMPEG_VERSION="7.0"
|
||||
ENV INCLUDED_FFMPEG_VERSIONS="${DEFAULT_FFMPEG_VERSION}:5.0"
|
||||
|
||||
RUN wget -q https://bootstrap.pypa.io/get-pip.py -O get-pip.py \
|
||||
&& sed -i 's/args.append("setuptools")/args.append("setuptools==77.0.3")/' get-pip.py \
|
||||
&& python3 get-pip.py "pip"
|
||||
|
||||
RUN --mount=type=bind,from=wheels,source=/wheels,target=/deps/wheels \
|
||||
python3 -m pip install --upgrade pip && \
|
||||
pip3 install -U /deps/wheels/*.whl
|
||||
|
||||
# Install MemryX runtime (requires libgomp (OpenMP) in the final docker image)
|
||||
RUN --mount=type=bind,source=docker/main/install_memryx.sh,target=/deps/install_memryx.sh \
|
||||
bash -c "bash /deps/install_memryx.sh"
|
||||
|
||||
COPY --from=deps-rootfs / /
|
||||
|
||||
RUN ldconfig
|
||||
|
||||
EXPOSE 5000
|
||||
EXPOSE 8554
|
||||
EXPOSE 8555/tcp 8555/udp
|
||||
@@ -172,13 +276,13 @@ ENV S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0
|
||||
ENTRYPOINT ["/init"]
|
||||
CMD []
|
||||
|
||||
HEALTHCHECK --start-period=120s --start-interval=5s --interval=15s --timeout=5s --retries=3 \
|
||||
CMD curl --fail --silent --show-error http://127.0.0.1:5000/api/version || exit 1
|
||||
HEALTHCHECK --start-period=300s --start-interval=5s --interval=15s --timeout=5s --retries=3 \
|
||||
CMD test -f /dev/shm/.frigate-is-stopping && exit 0; curl --fail --silent --show-error http://127.0.0.1:5000/api/version || exit 1
|
||||
|
||||
# Frigate deps with Node.js and NPM for devcontainer
|
||||
FROM deps AS devcontainer
|
||||
|
||||
# Do not start the actual Frigate service on devcontainer as it will be started by VSCode
|
||||
# Do not start the actual Frigate service on devcontainer as it will be started by VS Code
|
||||
# But start a fake service for simulating the logs
|
||||
COPY docker/main/fake_frigate_run /etc/s6-overlay/s6-rc.d/frigate/run
|
||||
|
||||
|
@@ -2,16 +2,22 @@
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
NGINX_VERSION="1.25.3"
|
||||
NGINX_VERSION="1.27.4"
|
||||
VOD_MODULE_VERSION="1.31"
|
||||
SECURE_TOKEN_MODULE_VERSION="1.5"
|
||||
SET_MISC_MODULE_VERSION="v0.33"
|
||||
NGX_DEVEL_KIT_VERSION="v0.3.3"
|
||||
|
||||
cp /etc/apt/sources.list /etc/apt/sources.list.d/sources-src.list
|
||||
sed -i 's|deb http|deb-src http|g' /etc/apt/sources.list.d/sources-src.list
|
||||
apt-get update
|
||||
source /etc/os-release
|
||||
|
||||
if [[ "$VERSION_ID" == "12" ]]; then
|
||||
sed -i '/^Types:/s/deb/& deb-src/' /etc/apt/sources.list.d/debian.sources
|
||||
else
|
||||
cp /etc/apt/sources.list /etc/apt/sources.list.d/sources-src.list
|
||||
sed -i 's|deb http|deb-src http|g' /etc/apt/sources.list.d/sources-src.list
|
||||
fi
|
||||
|
||||
apt-get update
|
||||
apt-get -yqq build-dep nginx
|
||||
|
||||
apt-get -yqq install --no-install-recommends ca-certificates wget
|
||||
|
@@ -4,7 +4,7 @@ from openvino.tools import mo
|
||||
ov_model = mo.convert_model(
|
||||
"/models/ssdlite_mobilenet_v2_coco_2018_05_09/frozen_inference_graph.pb",
|
||||
compress_to_fp16=True,
|
||||
transformations_config="/usr/local/lib/python3.9/dist-packages/openvino/tools/mo/front/tf/ssd_v2_support.json",
|
||||
transformations_config="/usr/local/lib/python3.11/dist-packages/openvino/tools/mo/front/tf/ssd_v2_support.json",
|
||||
tensorflow_object_detection_api_pipeline_config="/models/ssdlite_mobilenet_v2_coco_2018_05_09/pipeline.config",
|
||||
reverse_input_channels=True,
|
||||
)
|
||||
|
42
docker/main/build_pysqlite3.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
SQLITE3_VERSION="3.46.1"
|
||||
PYSQLITE3_VERSION="0.5.3"
|
||||
|
||||
# Fetch the pre-built sqlite amalgamation instead of building from source
|
||||
if [[ ! -d "sqlite" ]]; then
|
||||
mkdir sqlite
|
||||
cd sqlite
|
||||
|
||||
# Download the pre-built amalgamation from sqlite.org
|
||||
# For SQLite 3.46.1, the amalgamation version is 3460100
|
||||
SQLITE_AMALGAMATION_VERSION="3460100"
|
||||
|
||||
wget https://www.sqlite.org/2024/sqlite-amalgamation-${SQLITE_AMALGAMATION_VERSION}.zip -O sqlite-amalgamation.zip
|
||||
unzip sqlite-amalgamation.zip
|
||||
mv sqlite-amalgamation-${SQLITE_AMALGAMATION_VERSION}/* .
|
||||
rmdir sqlite-amalgamation-${SQLITE_AMALGAMATION_VERSION}
|
||||
rm sqlite-amalgamation.zip
|
||||
|
||||
cd ../
|
||||
fi
|
||||
|
||||
# Grab the pysqlite3 source code.
|
||||
if [[ ! -d "./pysqlite3" ]]; then
|
||||
git clone https://github.com/coleifer/pysqlite3.git
|
||||
fi
|
||||
|
||||
cd pysqlite3/
|
||||
git checkout ${PYSQLITE3_VERSION}
|
||||
|
||||
# Copy the sqlite3 source amalgamation into the pysqlite3 directory so we can
|
||||
# create a self-contained extension module.
|
||||
cp "../sqlite/sqlite3.c" ./
|
||||
cp "../sqlite/sqlite3.h" ./
|
||||
|
||||
# Create the wheel and put it in the /wheels dir.
|
||||
sed -i "s|name='pysqlite3-binary'|name=PACKAGE_NAME|g" setup.py
|
||||
python3 setup.py build_static
|
||||
pip3 wheel . -w /wheels
|
38
docker/main/build_sqlite_vec.sh
Executable file
@@ -0,0 +1,38 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
SQLITE_VEC_VERSION="0.1.3"
|
||||
|
||||
source /etc/os-release
|
||||
|
||||
if [[ "$VERSION_ID" == "12" ]]; then
|
||||
sed -i '/^Types:/s/deb/& deb-src/' /etc/apt/sources.list.d/debian.sources
|
||||
else
|
||||
cp /etc/apt/sources.list /etc/apt/sources.list.d/sources-src.list
|
||||
sed -i 's|deb http|deb-src http|g' /etc/apt/sources.list.d/sources-src.list
|
||||
fi
|
||||
|
||||
apt-get update
|
||||
apt-get -yqq build-dep sqlite3 gettext git
|
||||
|
||||
mkdir /tmp/sqlite_vec
|
||||
# Grab the sqlite_vec source code.
|
||||
wget -nv https://github.com/asg017/sqlite-vec/archive/refs/tags/v${SQLITE_VEC_VERSION}.tar.gz
|
||||
tar -zxf v${SQLITE_VEC_VERSION}.tar.gz -C /tmp/sqlite_vec
|
||||
|
||||
cd /tmp/sqlite_vec/sqlite-vec-${SQLITE_VEC_VERSION}
|
||||
|
||||
mkdir -p vendor
|
||||
wget -O sqlite-amalgamation.zip https://www.sqlite.org/2024/sqlite-amalgamation-3450300.zip
|
||||
unzip sqlite-amalgamation.zip
|
||||
mv sqlite-amalgamation-3450300/* vendor/
|
||||
rmdir sqlite-amalgamation-3450300
|
||||
rm sqlite-amalgamation.zip
|
||||
|
||||
# build loadable module
|
||||
make loadable
|
||||
|
||||
# install it
|
||||
cp dist/vec0.* /usr/local/lib
|
||||
|
@@ -6,72 +6,129 @@ apt-get -qq update
|
||||
|
||||
apt-get -qq install --no-install-recommends -y \
|
||||
apt-transport-https \
|
||||
ca-certificates \
|
||||
gnupg \
|
||||
wget \
|
||||
lbzip2 \
|
||||
procps vainfo \
|
||||
unzip locales tzdata libxml2 xz-utils \
|
||||
python3.9 \
|
||||
python3-pip \
|
||||
python3.11 \
|
||||
curl \
|
||||
lsof \
|
||||
jq \
|
||||
nethogs
|
||||
nethogs \
|
||||
libgl1 \
|
||||
libglib2.0-0 \
|
||||
libusb-1.0.0 \
|
||||
libgomp1 # memryx detector
|
||||
|
||||
# ensure python3 defaults to python3.9
|
||||
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.9 1
|
||||
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1
|
||||
|
||||
mkdir -p -m 600 /root/.gnupg
|
||||
|
||||
# add coral repo
|
||||
curl -fsSLo - https://packages.cloud.google.com/apt/doc/apt-key.gpg | \
|
||||
gpg --dearmor -o /etc/apt/trusted.gpg.d/google-cloud-packages-archive-keyring.gpg
|
||||
echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | tee /etc/apt/sources.list.d/coral-edgetpu.list
|
||||
echo "libedgetpu1-max libedgetpu/accepted-eula select true" | debconf-set-selections
|
||||
# install coral runtime
|
||||
wget -q -O /tmp/libedgetpu1-max.deb "https://github.com/feranick/libedgetpu/releases/download/16.0TF2.17.1-1/libedgetpu1-max_16.0tf2.17.1-1.bookworm_${TARGETARCH}.deb"
|
||||
unset DEBIAN_FRONTEND
|
||||
yes | dpkg -i /tmp/libedgetpu1-max.deb && export DEBIAN_FRONTEND=noninteractive
|
||||
rm /tmp/libedgetpu1-max.deb
|
||||
|
||||
# enable non-free repo in Debian
|
||||
if grep -q "Debian" /etc/issue; then
|
||||
sed -i -e's/ main/ main contrib non-free/g' /etc/apt/sources.list
|
||||
# install mesa-teflon-delegate from bookworm-backports
|
||||
# Only available for arm64 at the moment
|
||||
if [[ "${TARGETARCH}" == "arm64" ]]; then
|
||||
if [[ "${BASE_IMAGE}" == *"nvcr.io/nvidia/tensorrt"* ]]; then
|
||||
echo "Info: Skipping apt-get commands because BASE_IMAGE includes 'nvcr.io/nvidia/tensorrt' for arm64."
|
||||
else
|
||||
echo "deb http://deb.debian.org/debian bookworm-backports main" | tee /etc/apt/sources.list.d/bookworm-backbacks.list
|
||||
apt-get -qq update
|
||||
apt-get -qq install --no-install-recommends --no-install-suggests -y mesa-teflon-delegate/bookworm-backports
|
||||
fi
|
||||
fi
|
||||
|
||||
# coral drivers
|
||||
apt-get -qq update
|
||||
apt-get -qq install --no-install-recommends --no-install-suggests -y \
|
||||
libedgetpu1-max python3-tflite-runtime python3-pycoral
|
||||
|
||||
# btbn-ffmpeg -> amd64
|
||||
# ffmpeg -> amd64
|
||||
if [[ "${TARGETARCH}" == "amd64" ]]; then
|
||||
mkdir -p /usr/lib/btbn-ffmpeg
|
||||
wget -qO btbn-ffmpeg.tar.xz "https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2022-07-31-12-37/ffmpeg-n5.1-2-g915ef932a3-linux64-gpl-5.1.tar.xz"
|
||||
tar -xf btbn-ffmpeg.tar.xz -C /usr/lib/btbn-ffmpeg --strip-components 1
|
||||
rm -rf btbn-ffmpeg.tar.xz /usr/lib/btbn-ffmpeg/doc /usr/lib/btbn-ffmpeg/bin/ffplay
|
||||
mkdir -p /usr/lib/ffmpeg/5.0
|
||||
wget -qO ffmpeg.tar.xz "https://github.com/NickM-27/FFmpeg-Builds/releases/download/autobuild-2022-07-31-12-37/ffmpeg-n5.1-2-g915ef932a3-linux64-gpl-5.1.tar.xz"
|
||||
tar -xf ffmpeg.tar.xz -C /usr/lib/ffmpeg/5.0 --strip-components 1 amd64/bin/ffmpeg amd64/bin/ffprobe
|
||||
rm -rf ffmpeg.tar.xz
|
||||
mkdir -p /usr/lib/ffmpeg/7.0
|
||||
wget -qO ffmpeg.tar.xz "https://github.com/NickM-27/FFmpeg-Builds/releases/download/autobuild-2024-09-19-12-51/ffmpeg-n7.0.2-18-g3e6cec1286-linux64-gpl-7.0.tar.xz"
|
||||
tar -xf ffmpeg.tar.xz -C /usr/lib/ffmpeg/7.0 --strip-components 1 amd64/bin/ffmpeg amd64/bin/ffprobe
|
||||
rm -rf ffmpeg.tar.xz
|
||||
fi
|
||||
|
||||
# ffmpeg -> arm64
|
||||
if [[ "${TARGETARCH}" == "arm64" ]]; then
|
||||
mkdir -p /usr/lib/btbn-ffmpeg
|
||||
wget -qO btbn-ffmpeg.tar.xz "https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2022-07-31-12-37/ffmpeg-n5.1-2-g915ef932a3-linuxarm64-gpl-5.1.tar.xz"
|
||||
tar -xf btbn-ffmpeg.tar.xz -C /usr/lib/btbn-ffmpeg --strip-components 1
|
||||
rm -rf btbn-ffmpeg.tar.xz /usr/lib/btbn-ffmpeg/doc /usr/lib/btbn-ffmpeg/bin/ffplay
|
||||
mkdir -p /usr/lib/ffmpeg/5.0
|
||||
wget -qO ffmpeg.tar.xz "https://github.com/NickM-27/FFmpeg-Builds/releases/download/autobuild-2022-07-31-12-37/ffmpeg-n5.1-2-g915ef932a3-linuxarm64-gpl-5.1.tar.xz"
|
||||
tar -xf ffmpeg.tar.xz -C /usr/lib/ffmpeg/5.0 --strip-components 1 arm64/bin/ffmpeg arm64/bin/ffprobe
|
||||
rm -f ffmpeg.tar.xz
|
||||
mkdir -p /usr/lib/ffmpeg/7.0
|
||||
wget -qO ffmpeg.tar.xz "https://github.com/NickM-27/FFmpeg-Builds/releases/download/autobuild-2024-09-19-12-51/ffmpeg-n7.0.2-18-g3e6cec1286-linuxarm64-gpl-7.0.tar.xz"
|
||||
tar -xf ffmpeg.tar.xz -C /usr/lib/ffmpeg/7.0 --strip-components 1 arm64/bin/ffmpeg arm64/bin/ffprobe
|
||||
rm -f ffmpeg.tar.xz
|
||||
fi
|
||||
|
||||
# arch specific packages
|
||||
if [[ "${TARGETARCH}" == "amd64" ]]; then
|
||||
# use debian bookworm for hwaccel packages
|
||||
echo 'deb https://deb.debian.org/debian bookworm main contrib non-free' >/etc/apt/sources.list.d/debian-bookworm.list
|
||||
# Install non-free version of i965 driver
|
||||
sed -i -E "/^Components: main$/s/main/main contrib non-free non-free-firmware/" "/etc/apt/sources.list.d/debian.sources" \
|
||||
&& apt-get -qq update \
|
||||
&& apt-get install --no-install-recommends --no-install-suggests -y i965-va-driver-shaders \
|
||||
&& sed -i -E "/^Components: main contrib non-free non-free-firmware$/s/main contrib non-free non-free-firmware/main/" "/etc/apt/sources.list.d/debian.sources" \
|
||||
&& apt-get update
|
||||
|
||||
# install amd / intel-i965 driver packages
|
||||
apt-get -qq install --no-install-recommends --no-install-suggests -y \
|
||||
intel-gpu-tools onevpl-tools \
|
||||
libva-drm2 \
|
||||
mesa-va-drivers radeontop
|
||||
|
||||
# intel packages use zst compression so we need to update dpkg
|
||||
apt-get install -y dpkg
|
||||
|
||||
# use intel apt intel packages
|
||||
wget -qO - https://repositories.intel.com/gpu/intel-graphics.key | gpg --yes --dearmor --output /usr/share/keyrings/intel-graphics.gpg
|
||||
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/intel-graphics.gpg] https://repositories.intel.com/gpu/ubuntu jammy client" | tee /etc/apt/sources.list.d/intel-gpu-jammy.list
|
||||
apt-get -qq update
|
||||
apt-get -qq install --no-install-recommends --no-install-suggests -y \
|
||||
intel-opencl-icd \
|
||||
mesa-va-drivers radeontop libva-drm2 intel-media-va-driver-non-free i965-va-driver libmfx1 intel-gpu-tools
|
||||
# something about this dependency requires it to be installed in a separate call rather than in the line above
|
||||
apt-get -qq install --no-install-recommends --no-install-suggests -y \
|
||||
i965-va-driver-shaders
|
||||
rm -f /etc/apt/sources.list.d/debian-bookworm.list
|
||||
intel-media-va-driver-non-free libmfx1 libmfxgen1 libvpl2
|
||||
|
||||
apt-get -qq install -y ocl-icd-libopencl1
|
||||
|
||||
rm -f /usr/share/keyrings/intel-graphics.gpg
|
||||
rm -f /etc/apt/sources.list.d/intel-gpu-jammy.list
|
||||
|
||||
# install legacy and standard intel icd and level-zero-gpu
|
||||
# see https://github.com/intel/compute-runtime/blob/master/LEGACY_PLATFORMS.md for more info
|
||||
# needed core package
|
||||
wget https://github.com/intel/compute-runtime/releases/download/24.52.32224.5/libigdgmm12_22.5.5_amd64.deb
|
||||
dpkg -i libigdgmm12_22.5.5_amd64.deb
|
||||
rm libigdgmm12_22.5.5_amd64.deb
|
||||
|
||||
# legacy packages
|
||||
wget https://github.com/intel/compute-runtime/releases/download/24.35.30872.36/intel-opencl-icd-legacy1_24.35.30872.36_amd64.deb
|
||||
wget https://github.com/intel/compute-runtime/releases/download/24.35.30872.36/intel-level-zero-gpu-legacy1_1.5.30872.36_amd64.deb
|
||||
wget https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.17537.24/intel-igc-opencl_1.0.17537.24_amd64.deb
|
||||
wget https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.17537.24/intel-igc-core_1.0.17537.24_amd64.deb
|
||||
# standard packages
|
||||
wget https://github.com/intel/compute-runtime/releases/download/24.52.32224.5/intel-opencl-icd_24.52.32224.5_amd64.deb
|
||||
wget https://github.com/intel/compute-runtime/releases/download/24.52.32224.5/intel-level-zero-gpu_1.6.32224.5_amd64.deb
|
||||
wget https://github.com/intel/intel-graphics-compiler/releases/download/v2.5.6/intel-igc-opencl-2_2.5.6+18417_amd64.deb
|
||||
wget https://github.com/intel/intel-graphics-compiler/releases/download/v2.5.6/intel-igc-core-2_2.5.6+18417_amd64.deb
|
||||
|
||||
dpkg -i *.deb
|
||||
rm *.deb
|
||||
fi
|
||||
|
||||
if [[ "${TARGETARCH}" == "arm64" ]]; then
|
||||
apt-get -qq install --no-install-recommends --no-install-suggests -y \
|
||||
libva-drm2 mesa-va-drivers
|
||||
libva-drm2 mesa-va-drivers radeontop
|
||||
fi
|
||||
|
||||
# install vulkan
|
||||
apt-get -qq install --no-install-recommends --no-install-suggests -y \
|
||||
libvulkan1 mesa-vulkan-drivers
|
||||
|
||||
apt-get purge gnupg apt-transport-https xz-utils -y
|
||||
apt-get clean autoclean -y
|
||||
apt-get autoremove --purge -y
|
||||
|
14
docker/main/install_hailort.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
hailo_version="4.21.0"
|
||||
|
||||
if [[ "${TARGETARCH}" == "amd64" ]]; then
|
||||
arch="x86_64"
|
||||
elif [[ "${TARGETARCH}" == "arm64" ]]; then
|
||||
arch="aarch64"
|
||||
fi
|
||||
|
||||
wget -qO- "https://github.com/frigate-nvr/hailort/releases/download/v${hailo_version}/hailort-debian12-${TARGETARCH}.tar.gz" | tar -C / -xzf -
|
||||
wget -P /wheels/ "https://github.com/frigate-nvr/hailort/releases/download/v${hailo_version}/hailort-${hailo_version}-cp311-cp311-linux_${arch}.whl"
|
31
docker/main/install_memryx.sh
Normal file
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Download the MxAccl for Frigate github release
|
||||
wget https://github.com/memryx/mx_accl_frigate/archive/refs/heads/main.zip -O /tmp/mxaccl.zip
|
||||
unzip /tmp/mxaccl.zip -d /tmp
|
||||
mv /tmp/mx_accl_frigate-main /opt/mx_accl_frigate
|
||||
rm /tmp/mxaccl.zip
|
||||
|
||||
# Install Python dependencies
|
||||
pip3 install -r /opt/mx_accl_frigate/freeze
|
||||
|
||||
# Link the Python package dynamically
|
||||
SITE_PACKAGES=$(python3 -c "import site; print(site.getsitepackages()[0])")
|
||||
ln -s /opt/mx_accl_frigate/memryx "$SITE_PACKAGES/memryx"
|
||||
|
||||
# Copy architecture-specific shared libraries
|
||||
ARCH=$(uname -m)
|
||||
if [[ "$ARCH" == "x86_64" ]]; then
|
||||
cp /opt/mx_accl_frigate/memryx/x86/libmemx.so* /usr/lib/x86_64-linux-gnu/
|
||||
cp /opt/mx_accl_frigate/memryx/x86/libmx_accl.so* /usr/lib/x86_64-linux-gnu/
|
||||
elif [[ "$ARCH" == "aarch64" ]]; then
|
||||
cp /opt/mx_accl_frigate/memryx/arm/libmemx.so* /usr/lib/aarch64-linux-gnu/
|
||||
cp /opt/mx_accl_frigate/memryx/arm/libmx_accl.so* /usr/lib/aarch64-linux-gnu/
|
||||
else
|
||||
echo "Unsupported architecture: $ARCH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Refresh linker cache
|
||||
ldconfig
|
@@ -2,7 +2,7 @@
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
s6_version="3.1.5.0"
|
||||
s6_version="3.2.1.0"
|
||||
|
||||
if [[ "${TARGETARCH}" == "amd64" ]]; then
|
||||
s6_arch="x86_64"
|
||||
|
16
docker/main/install_tempio.sh
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
tempio_version="2021.09.0"
|
||||
|
||||
if [[ "${TARGETARCH}" == "amd64" ]]; then
|
||||
arch="amd64"
|
||||
elif [[ "${TARGETARCH}" == "arm64" ]]; then
|
||||
arch="aarch64"
|
||||
fi
|
||||
|
||||
mkdir -p /rootfs/usr/local/tempio/bin
|
||||
|
||||
wget -q -O /rootfs/usr/local/tempio/bin/tempio "https://github.com/home-assistant/tempio/releases/download/${tempio_version}/tempio_${arch}"
|
||||
chmod 755 /rootfs/usr/local/tempio/bin/tempio
|
@@ -1 +1,4 @@
|
||||
ruff
|
||||
|
||||
# types
|
||||
types-peewee == 3.17.*
|
||||
|
@@ -1,33 +1,83 @@
|
||||
aiofiles == 24.1.*
|
||||
click == 8.1.*
|
||||
Flask == 3.0.*
|
||||
Flask_Limiter == 3.7.*
|
||||
imutils == 0.5.*
|
||||
joserfc == 0.10.*
|
||||
markupsafe == 2.1.*
|
||||
matplotlib == 3.8.*
|
||||
# FastAPI
|
||||
aiohttp == 3.12.*
|
||||
starlette == 0.47.*
|
||||
starlette-context == 0.4.*
|
||||
fastapi[standard-no-fastapi-cloud-cli] == 0.116.*
|
||||
uvicorn == 0.35.*
|
||||
slowapi == 0.1.*
|
||||
joserfc == 1.2.*
|
||||
cryptography == 44.0.*
|
||||
pathvalidate == 3.3.*
|
||||
markupsafe == 3.0.*
|
||||
python-multipart == 0.0.20
|
||||
# Classification Model Training
|
||||
tensorflow == 2.19.* ; platform_machine == 'aarch64'
|
||||
tensorflow-cpu == 2.19.* ; platform_machine == 'x86_64'
|
||||
# General
|
||||
mypy == 1.6.1
|
||||
numpy == 1.26.*
|
||||
onvif_zeep == 0.2.12
|
||||
opencv-python-headless == 4.9.0.*
|
||||
onvif-zeep-async == 4.0.*
|
||||
paho-mqtt == 2.1.*
|
||||
pandas == 2.2.*
|
||||
peewee == 3.17.*
|
||||
peewee_migrate == 1.12.*
|
||||
psutil == 5.9.*
|
||||
pydantic == 2.7.*
|
||||
peewee_migrate == 1.13.*
|
||||
psutil == 7.1.*
|
||||
pydantic == 2.10.*
|
||||
git+https://github.com/fbcotter/py3nvml#egg=py3nvml
|
||||
PyYAML == 6.0.*
|
||||
pytz == 2024.1
|
||||
pyzmq == 26.0.*
|
||||
pytz == 2025.*
|
||||
pyzmq == 26.2.*
|
||||
ruamel.yaml == 0.18.*
|
||||
tzlocal == 5.2
|
||||
types-PyYAML == 6.0.*
|
||||
requests == 2.32.*
|
||||
types-requests == 2.32.*
|
||||
scipy == 1.13.*
|
||||
norfair == 2.2.*
|
||||
norfair == 2.3.*
|
||||
setproctitle == 1.3.*
|
||||
ws4py == 0.5.*
|
||||
unidecode == 1.3.*
|
||||
onnxruntime == 1.16.*
|
||||
openvino == 2024.1.*
|
||||
titlecase == 2.4.*
|
||||
# Image Manipulation
|
||||
numpy == 1.26.*
|
||||
opencv-python-headless == 4.11.0.*
|
||||
opencv-contrib-python == 4.11.0.*
|
||||
scipy == 1.16.*
|
||||
# OpenVino & ONNX
|
||||
openvino == 2025.3.*
|
||||
onnxruntime == 1.22.*
|
||||
# Embeddings
|
||||
transformers == 4.45.*
|
||||
# Generative AI
|
||||
google-generativeai == 0.8.*
|
||||
ollama == 0.5.*
|
||||
openai == 1.65.*
|
||||
# push notifications
|
||||
py-vapid == 1.9.*
|
||||
pywebpush == 2.0.*
|
||||
# alpr
|
||||
pyclipper == 1.3.*
|
||||
shapely == 2.0.*
|
||||
Levenshtein==0.26.*
|
||||
# HailoRT Wheels
|
||||
appdirs==1.4.*
|
||||
argcomplete==2.0.*
|
||||
contextlib2==0.6.*
|
||||
distlib==0.3.*
|
||||
filelock==3.8.*
|
||||
future==0.18.*
|
||||
importlib-metadata==5.1.*
|
||||
importlib-resources==5.1.*
|
||||
netaddr==0.8.*
|
||||
netifaces==0.10.*
|
||||
verboselogs==1.7.*
|
||||
virtualenv==20.17.*
|
||||
prometheus-client == 0.21.*
|
||||
# TFLite
|
||||
tflite_runtime @ https://github.com/frigate-nvr/TFlite-builds/releases/download/v2.17.1/tflite_runtime-2.17.1-cp311-cp311-linux_x86_64.whl; platform_machine == 'x86_64'
|
||||
tflite_runtime @ https://github.com/feranick/TFlite-builds/releases/download/v2.17.1/tflite_runtime-2.17.1-cp311-cp311-linux_aarch64.whl; platform_machine == 'aarch64'
|
||||
# audio transcription
|
||||
sherpa-onnx==1.12.*
|
||||
faster-whisper==1.1.*
|
||||
librosa==0.11.*
|
||||
soundfile==0.13.*
|
||||
# DeGirum detector
|
||||
degirum == 0.16.*
|
||||
|
@@ -1,2 +1,2 @@
|
||||
scikit-build == 0.17.*
|
||||
scikit-build == 0.18.*
|
||||
nvidia-pyindex
|
||||
|
@@ -10,16 +10,21 @@ echo "[INFO] Starting certsync..."
|
||||
|
||||
lefile="/etc/letsencrypt/live/frigate/fullchain.pem"
|
||||
|
||||
tls_enabled=`python3 /usr/local/nginx/get_listen_settings.py | jq -r .tls.enabled`
|
||||
|
||||
while true
|
||||
do
|
||||
if [[ "$tls_enabled" == 'false' ]]; then
|
||||
sleep 9999
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ ! -e $lefile ]
|
||||
then
|
||||
echo "[ERROR] TLS certificate does not exist: $lefile"
|
||||
fi
|
||||
|
||||
leprint=`openssl x509 -in $lefile -fingerprint -noout || echo 'failed'`
|
||||
leprint=`openssl x509 -in $lefile -fingerprint -noout 2>&1 || echo 'failed'`
|
||||
|
||||
case "$leprint" in
|
||||
*Fingerprint*)
|
||||
@@ -29,7 +34,7 @@ do
|
||||
;;
|
||||
esac
|
||||
|
||||
liveprint=`echo | openssl s_client -showcerts -connect 127.0.0.1:443 2>&1 | openssl x509 -fingerprint | grep -i fingerprint || echo 'failed'`
|
||||
liveprint=`echo | openssl s_client -showcerts -connect 127.0.0.1:8971 2>&1 | openssl x509 -fingerprint 2>&1 | grep -i fingerprint || echo 'failed'`
|
||||
|
||||
case "$liveprint" in
|
||||
*Fingerprint*)
|
||||
|
@@ -4,47 +4,25 @@
|
||||
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
# opt out of openvino telemetry
|
||||
if [ -e /usr/local/bin/opt_in_out ]; then
|
||||
/usr/local/bin/opt_in_out --opt_out > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
# Logs should be sent to stdout so that s6 can collect them
|
||||
|
||||
# Tell S6-Overlay not to restart this service
|
||||
s6-svc -O .
|
||||
|
||||
function migrate_db_path() {
|
||||
# Find config file in yaml or yml, but prefer yaml
|
||||
local config_file="${CONFIG_FILE:-"/config/config.yml"}"
|
||||
local config_file_yaml="${config_file//.yml/.yaml}"
|
||||
if [[ -f "${config_file_yaml}" ]]; then
|
||||
config_file="${config_file_yaml}"
|
||||
elif [[ ! -f "${config_file}" ]]; then
|
||||
echo "[ERROR] Frigate config file not found"
|
||||
return 1
|
||||
fi
|
||||
unset config_file_yaml
|
||||
|
||||
# Use yq to check if database.path is set
|
||||
local user_db_path
|
||||
user_db_path=$(yq eval '.database.path' "${config_file}")
|
||||
|
||||
if [[ "${user_db_path}" == "null" ]]; then
|
||||
local previous_db_path="/media/frigate/frigate.db"
|
||||
local new_db_dir="/config"
|
||||
if [[ -f "${previous_db_path}" ]]; then
|
||||
if mountpoint --quiet "${new_db_dir}"; then
|
||||
# /config is a mount point, move the db
|
||||
echo "[INFO] Moving db from '${previous_db_path}' to the '${new_db_dir}' dir..."
|
||||
# Move all files that starts with frigate.db to the new directory
|
||||
mv -vf "${previous_db_path}"* "${new_db_dir}"
|
||||
else
|
||||
echo "[ERROR] Trying to migrate the db path from '${previous_db_path}' to the '${new_db_dir}' dir, but '${new_db_dir}' is not a mountpoint, please mount the '${new_db_dir}' dir"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
function set_libva_version() {
|
||||
local ffmpeg_path
|
||||
ffmpeg_path=$(python3 /usr/local/ffmpeg/get_ffmpeg_path.py)
|
||||
LIBAVFORMAT_VERSION_MAJOR=$("$ffmpeg_path" -version | grep -Po "libavformat\W+\K\d+")
|
||||
export LIBAVFORMAT_VERSION_MAJOR
|
||||
}
|
||||
|
||||
echo "[INFO] Preparing Frigate..."
|
||||
migrate_db_path
|
||||
export LIBAVFORMAT_VERSION_MAJOR=$(ffmpeg -version | grep -Po 'libavformat\W+\K\d+')
|
||||
set_libva_version
|
||||
|
||||
echo "[INFO] Starting Frigate..."
|
||||
|
||||
|
@@ -43,7 +43,46 @@ function get_ip_and_port_from_supervisor() {
|
||||
export FRIGATE_GO2RTC_WEBRTC_CANDIDATE_INTERNAL="${ip_address}:${webrtc_port}"
|
||||
}
|
||||
|
||||
export LIBAVFORMAT_VERSION_MAJOR=$(ffmpeg -version | grep -Po 'libavformat\W+\K\d+')
|
||||
function set_libva_version() {
|
||||
local ffmpeg_path
|
||||
ffmpeg_path=$(python3 /usr/local/ffmpeg/get_ffmpeg_path.py)
|
||||
LIBAVFORMAT_VERSION_MAJOR=$("$ffmpeg_path" -version | grep -Po "libavformat\W+\K\d+")
|
||||
export LIBAVFORMAT_VERSION_MAJOR
|
||||
}
|
||||
|
||||
function setup_homekit_config() {
|
||||
local config_path="$1"
|
||||
|
||||
if [[ ! -f "${config_path}" ]]; then
|
||||
echo "[INFO] Creating empty HomeKit config file..."
|
||||
echo '{}' > "${config_path}"
|
||||
fi
|
||||
|
||||
# Convert YAML to JSON for jq processing
|
||||
local temp_json="/tmp/cache/homekit_config.json"
|
||||
yq eval -o=json "${config_path}" > "${temp_json}" 2>/dev/null || {
|
||||
echo "[WARNING] Failed to convert HomeKit config to JSON, skipping cleanup"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Use jq to filter and keep only the homekit section
|
||||
local cleaned_json="/tmp/cache/homekit_cleaned.json"
|
||||
jq '
|
||||
# Keep only the homekit section if it exists, otherwise empty object
|
||||
if has("homekit") then {homekit: .homekit} else {homekit: {}} end
|
||||
' "${temp_json}" > "${cleaned_json}" 2>/dev/null || echo '{"homekit": {}}' > "${cleaned_json}"
|
||||
|
||||
# Convert back to YAML and write to the config file
|
||||
yq eval -P "${cleaned_json}" > "${config_path}" 2>/dev/null || {
|
||||
echo "[WARNING] Failed to convert cleaned config to YAML, creating minimal config"
|
||||
echo '{"homekit": {}}' > "${config_path}"
|
||||
}
|
||||
|
||||
# Clean up temp files
|
||||
rm -f "${temp_json}" "${cleaned_json}"
|
||||
}
|
||||
|
||||
set_libva_version
|
||||
|
||||
if [[ -f "/dev/shm/go2rtc.yaml" ]]; then
|
||||
echo "[INFO] Removing stale config from last run..."
|
||||
@@ -54,7 +93,7 @@ if [[ ! -f "/dev/shm/go2rtc.yaml" ]]; then
|
||||
echo "[INFO] Preparing new go2rtc config..."
|
||||
|
||||
if [[ -n "${SUPERVISOR_TOKEN:-}" ]]; then
|
||||
# Running as a Home Assistant add-on, infer the IP address and port
|
||||
# Running as a Home Assistant Add-on, infer the IP address and port
|
||||
get_ip_and_port_from_supervisor
|
||||
fi
|
||||
|
||||
@@ -63,6 +102,10 @@ else
|
||||
echo "[WARNING] Unable to remove existing go2rtc config. Changes made to your frigate config file may not be recognized. Please remove the /dev/shm/go2rtc.yaml from your docker host manually."
|
||||
fi
|
||||
|
||||
# HomeKit configuration persistence setup
|
||||
readonly homekit_config_path="/config/go2rtc_homekit.yml"
|
||||
setup_homekit_config "${homekit_config_path}"
|
||||
|
||||
readonly config_path="/config"
|
||||
|
||||
if [[ -x "${config_path}/go2rtc" ]]; then
|
||||
@@ -75,5 +118,7 @@ fi
|
||||
echo "[INFO] Starting go2rtc..."
|
||||
|
||||
# Replace the bash process with the go2rtc process, redirecting stderr to stdout
|
||||
# Use HomeKit config as the primary config so writebacks go there
|
||||
# The main config from Frigate will be loaded as a secondary config
|
||||
exec 2>&1
|
||||
exec "${binary_path}" -config=/dev/shm/go2rtc.yaml
|
||||
exec "${binary_path}" -config="${homekit_config_path}" -config=/dev/shm/go2rtc.yaml
|
||||
|
@@ -8,16 +8,59 @@ set -o errexit -o nounset -o pipefail
|
||||
|
||||
echo "[INFO] Starting NGINX..."
|
||||
|
||||
# Taken from https://github.com/felipecrs/cgroup-scripts/commits/master/get_cpus.sh
|
||||
function get_cpus() {
|
||||
local quota=""
|
||||
local period=""
|
||||
|
||||
if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
|
||||
if [ -f /sys/fs/cgroup/cpu.max ]; then
|
||||
read -r quota period </sys/fs/cgroup/cpu.max
|
||||
if [ "$quota" = "max" ]; then
|
||||
quota=""
|
||||
period=""
|
||||
fi
|
||||
else
|
||||
echo "[WARN] /sys/fs/cgroup/cpu.max not found. Falling back to /proc/cpuinfo." >&2
|
||||
fi
|
||||
else
|
||||
if [ -f /sys/fs/cgroup/cpu/cpu.cfs_quota_us ] && [ -f /sys/fs/cgroup/cpu/cpu.cfs_period_us ]; then
|
||||
quota=$(cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us)
|
||||
period=$(cat /sys/fs/cgroup/cpu/cpu.cfs_period_us)
|
||||
|
||||
if [ "$quota" = "-1" ]; then
|
||||
quota=""
|
||||
period=""
|
||||
fi
|
||||
else
|
||||
echo "[WARN] /sys/fs/cgroup/cpu/cpu.cfs_quota_us or /sys/fs/cgroup/cpu/cpu.cfs_period_us not found. Falling back to /proc/cpuinfo." >&2
|
||||
fi
|
||||
fi
|
||||
|
||||
local cpus
|
||||
if [ "${period}" != "0" ] && [ -n "${quota}" ] && [ -n "${period}" ]; then
|
||||
cpus=$((quota / period))
|
||||
if [ "$cpus" -eq 0 ]; then
|
||||
cpus=1
|
||||
fi
|
||||
else
|
||||
cpus=$(grep -c ^processor /proc/cpuinfo)
|
||||
fi
|
||||
|
||||
printf '%s' "$cpus"
|
||||
}
|
||||
|
||||
function set_worker_processes() {
|
||||
# Capture number of assigned CPUs to calculate worker processes
|
||||
local proc_count
|
||||
local cpus
|
||||
|
||||
if proc_count=$(nproc --all) && [[ $proc_count -gt 4 ]]; then
|
||||
proc_count=4;
|
||||
cpus=$(get_cpus)
|
||||
if [[ "${cpus}" -gt 4 ]]; then
|
||||
cpus=4
|
||||
fi
|
||||
|
||||
# we need to catch any errors because sed will fail if user has bind mounted a custom nginx file
|
||||
sed -i "s/worker_processes auto;/worker_processes ${proc_count};/" /usr/local/nginx/conf/nginx.conf || true
|
||||
sed -i "s/worker_processes auto;/worker_processes ${cpus};/" /usr/local/nginx/conf/nginx.conf || true
|
||||
}
|
||||
|
||||
set_worker_processes
|
||||
@@ -33,9 +76,19 @@ if [ ! \( -f "$letsencrypt_path/privkey.pem" -a -f "$letsencrypt_path/fullchain.
|
||||
echo "[INFO] No TLS certificate found. Generating a self signed certificate..."
|
||||
openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \
|
||||
-subj "/O=FRIGATE DEFAULT CERT/CN=*" \
|
||||
-keyout "$letsencrypt_path/privkey.pem" -out "$letsencrypt_path/fullchain.pem"
|
||||
-keyout "$letsencrypt_path/privkey.pem" -out "$letsencrypt_path/fullchain.pem" 2>/dev/null
|
||||
fi
|
||||
|
||||
# build templates for optional FRIGATE_BASE_PATH environment variable
|
||||
python3 /usr/local/nginx/get_base_path.py | \
|
||||
tempio -template /usr/local/nginx/templates/base_path.gotmpl \
|
||||
-out /usr/local/nginx/conf/base_path.conf
|
||||
|
||||
# build templates for optional TLS support
|
||||
python3 /usr/local/nginx/get_listen_settings.py | \
|
||||
tempio -template /usr/local/nginx/templates/listen.gotmpl \
|
||||
-out /usr/local/nginx/conf/listen.conf
|
||||
|
||||
# Replace the bash process with the NGINX process, redirecting stderr to stdout
|
||||
exec 2>&1
|
||||
exec \
|
||||
|
146
docker/main/rootfs/etc/s6-overlay/s6-rc.d/prepare/run
Executable file
@@ -0,0 +1,146 @@
|
||||
#!/command/with-contenv bash
|
||||
# shellcheck shell=bash
|
||||
# Do preparation tasks before starting the main services
|
||||
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
function migrate_addon_config_dir() {
|
||||
local home_assistant_config_dir="/homeassistant"
|
||||
|
||||
if ! mountpoint --quiet "${home_assistant_config_dir}"; then
|
||||
# Not running as a Home Assistant Add-on
|
||||
return 0
|
||||
fi
|
||||
|
||||
local config_dir="/config"
|
||||
local new_config_file="${config_dir}/config.yml"
|
||||
local new_config_file_yaml="${new_config_file//.yml/.yaml}"
|
||||
if [[ -f "${new_config_file_yaml}" || -f "${new_config_file}" ]]; then
|
||||
# Already migrated
|
||||
return 0
|
||||
fi
|
||||
|
||||
local old_config_file="${home_assistant_config_dir}/frigate.yml"
|
||||
local old_config_file_yaml="${old_config_file//.yml/.yaml}"
|
||||
if [[ -f "${old_config_file}" ]]; then
|
||||
:
|
||||
elif [[ -f "${old_config_file_yaml}" ]]; then
|
||||
old_config_file="${old_config_file_yaml}"
|
||||
new_config_file="${new_config_file_yaml}"
|
||||
else
|
||||
# Nothing to migrate
|
||||
return 0
|
||||
fi
|
||||
unset old_config_file_yaml new_config_file_yaml
|
||||
|
||||
echo "[INFO] Starting migration from Home Assistant config dir to Add-on config dir..." >&2
|
||||
|
||||
local db_path
|
||||
db_path=$(yq -r '.database.path' "${old_config_file}")
|
||||
if [[ "${db_path}" == "null" ]]; then
|
||||
db_path="${config_dir}/frigate.db"
|
||||
fi
|
||||
if [[ "${db_path}" == "${config_dir}/"* ]]; then
|
||||
# replace /config/ prefix with /homeassistant/
|
||||
local old_db_path="${home_assistant_config_dir}/${db_path:8}"
|
||||
|
||||
if [[ -f "${old_db_path}" ]]; then
|
||||
local new_db_dir
|
||||
new_db_dir="$(dirname "${db_path}")"
|
||||
echo "[INFO] Migrating database from '${old_db_path}' to '${new_db_dir}' dir..." >&2
|
||||
mkdir -vp "${new_db_dir}"
|
||||
mv -vf "${old_db_path}" "${new_db_dir}"
|
||||
local db_file
|
||||
for db_file in "${old_db_path}"-shm "${old_db_path}"-wal; do
|
||||
if [[ -f "${db_file}" ]]; then
|
||||
mv -vf "${db_file}" "${new_db_dir}"
|
||||
fi
|
||||
done
|
||||
unset db_file
|
||||
fi
|
||||
fi
|
||||
|
||||
local config_entry
|
||||
for config_entry in .model.path .model.labelmap_path .ffmpeg.path .mqtt.tls_ca_certs .mqtt.tls_client_cert .mqtt.tls_client_key; do
|
||||
local config_entry_path
|
||||
config_entry_path=$(yq -r "${config_entry}" "${old_config_file}")
|
||||
if [[ "${config_entry_path}" == "${config_dir}/"* ]]; then
|
||||
# replace /config/ prefix with /homeassistant/
|
||||
local old_config_entry_path="${home_assistant_config_dir}/${config_entry_path:8}"
|
||||
|
||||
if [[ -f "${old_config_entry_path}" ]]; then
|
||||
local new_config_entry_entry
|
||||
new_config_entry_entry="$(dirname "${config_entry_path}")"
|
||||
echo "[INFO] Migrating ${config_entry} from '${old_config_entry_path}' to '${config_entry_path}'..." >&2
|
||||
mkdir -vp "${new_config_entry_entry}"
|
||||
mv -vf "${old_config_entry_path}" "${config_entry_path}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
local old_model_cache_path="${home_assistant_config_dir}/model_cache"
|
||||
if [[ -d "${old_model_cache_path}" ]]; then
|
||||
echo "[INFO] Migrating '${old_model_cache_path}' to '${config_dir}'..." >&2
|
||||
mv -f "${old_model_cache_path}" "${config_dir}"
|
||||
fi
|
||||
|
||||
echo "[INFO] Migrating other files from '${home_assistant_config_dir}' to '${config_dir}'..." >&2
|
||||
local file
|
||||
for file in .exports .jwt_secret .timeline .vacuum go2rtc; do
|
||||
file="${home_assistant_config_dir}/${file}"
|
||||
if [[ -f "${file}" ]]; then
|
||||
mv -vf "${file}" "${config_dir}"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "[INFO] Migrating config file from '${old_config_file}' to '${new_config_file}'..." >&2
|
||||
mv -vf "${old_config_file}" "${new_config_file}"
|
||||
|
||||
echo "[INFO] Migration from Home Assistant config dir to Add-on config dir completed." >&2
|
||||
}
|
||||
|
||||
function migrate_db_from_media_to_config() {
|
||||
# Find config file in yml or yaml, but prefer yml
|
||||
local config_file="${CONFIG_FILE:-"/config/config.yml"}"
|
||||
local config_file_yaml="${config_file//.yml/.yaml}"
|
||||
if [[ -f "${config_file}" ]]; then
|
||||
:
|
||||
elif [[ -f "${config_file_yaml}" ]]; then
|
||||
config_file="${config_file_yaml}"
|
||||
else
|
||||
# Frigate will create the config file on startup
|
||||
return 0
|
||||
fi
|
||||
unset config_file_yaml
|
||||
|
||||
local user_db_path
|
||||
user_db_path=$(yq -r '.database.path' "${config_file}")
|
||||
if [[ "${user_db_path}" == "null" ]]; then
|
||||
local old_db_path="/media/frigate/frigate.db"
|
||||
local new_db_dir="/config"
|
||||
if [[ -f "${old_db_path}" ]]; then
|
||||
echo "[INFO] Migrating database from '${old_db_path}' to '${new_db_dir}' dir..." >&2
|
||||
if mountpoint --quiet "${new_db_dir}"; then
|
||||
# /config is a mount point, move the db
|
||||
mv -vf "${old_db_path}" "${new_db_dir}"
|
||||
local db_file
|
||||
for db_file in "${old_db_path}"-shm "${old_db_path}"-wal; do
|
||||
if [[ -f "${db_file}" ]]; then
|
||||
mv -vf "${db_file}" "${new_db_dir}"
|
||||
fi
|
||||
done
|
||||
unset db_file
|
||||
else
|
||||
echo "[ERROR] Trying to migrate the database path from '${old_db_path}' to '${new_db_dir}' dir, but '${new_db_dir}' is not a mountpoint, please mount the '${new_db_dir}' dir" >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# remove leftover from last run, not normally needed, but just in case
|
||||
# used by the docker healthcheck
|
||||
rm -f /dev/shm/.frigate-is-stopping
|
||||
|
||||
migrate_addon_config_dir
|
||||
migrate_db_from_media_to_config
|
1
docker/main/rootfs/etc/s6-overlay/s6-rc.d/prepare/up
Normal file
@@ -0,0 +1 @@
|
||||
/etc/s6-overlay/s6-rc.d/prepare/run
|
80
docker/main/rootfs/labelmap/coco-80.txt
Normal file
@@ -0,0 +1,80 @@
|
||||
0 person
|
||||
1 bicycle
|
||||
2 car
|
||||
3 motorcycle
|
||||
4 airplane
|
||||
5 car
|
||||
6 train
|
||||
7 car
|
||||
8 boat
|
||||
9 traffic light
|
||||
10 fire hydrant
|
||||
11 stop sign
|
||||
12 parking meter
|
||||
13 bench
|
||||
14 bird
|
||||
15 cat
|
||||
16 dog
|
||||
17 horse
|
||||
18 sheep
|
||||
19 cow
|
||||
20 elephant
|
||||
21 bear
|
||||
22 zebra
|
||||
23 giraffe
|
||||
24 backpack
|
||||
25 umbrella
|
||||
26 handbag
|
||||
27 tie
|
||||
28 suitcase
|
||||
29 frisbee
|
||||
30 skis
|
||||
31 snowboard
|
||||
32 sports ball
|
||||
33 kite
|
||||
34 baseball bat
|
||||
35 baseball glove
|
||||
36 skateboard
|
||||
37 surfboard
|
||||
38 tennis racket
|
||||
39 bottle
|
||||
40 wine glass
|
||||
41 cup
|
||||
42 fork
|
||||
43 knife
|
||||
44 spoon
|
||||
45 bowl
|
||||
46 banana
|
||||
47 apple
|
||||
48 sandwich
|
||||
49 orange
|
||||
50 broccoli
|
||||
51 carrot
|
||||
52 hot dog
|
||||
53 pizza
|
||||
54 donut
|
||||
55 cake
|
||||
56 chair
|
||||
57 couch
|
||||
58 potted plant
|
||||
59 bed
|
||||
60 dining table
|
||||
61 toilet
|
||||
62 tv
|
||||
63 laptop
|
||||
64 mouse
|
||||
65 remote
|
||||
66 keyboard
|
||||
67 cell phone
|
||||
68 microwave
|
||||
69 oven
|
||||
70 toaster
|
||||
71 sink
|
||||
72 refrigerator
|
||||
73 book
|
||||
74 clock
|
||||
75 vase
|
||||
76 scissors
|
||||
77 teddy bear
|
||||
78 hair drier
|
||||
79 toothbrush
|
91
docker/main/rootfs/labelmap/coco.txt
Normal file
@@ -0,0 +1,91 @@
|
||||
0 person
|
||||
1 bicycle
|
||||
2 car
|
||||
3 motorcycle
|
||||
4 airplane
|
||||
5 bus
|
||||
6 train
|
||||
7 car
|
||||
8 boat
|
||||
9 traffic light
|
||||
10 fire hydrant
|
||||
11 street sign
|
||||
12 stop sign
|
||||
13 parking meter
|
||||
14 bench
|
||||
15 bird
|
||||
16 cat
|
||||
17 dog
|
||||
18 horse
|
||||
19 sheep
|
||||
20 cow
|
||||
21 elephant
|
||||
22 bear
|
||||
23 zebra
|
||||
24 giraffe
|
||||
25 hat
|
||||
26 backpack
|
||||
27 umbrella
|
||||
28 shoe
|
||||
29 eye glasses
|
||||
30 handbag
|
||||
31 tie
|
||||
32 suitcase
|
||||
33 frisbee
|
||||
34 skis
|
||||
35 snowboard
|
||||
36 sports ball
|
||||
37 kite
|
||||
38 baseball bat
|
||||
39 baseball glove
|
||||
40 skateboard
|
||||
41 surfboard
|
||||
42 tennis racket
|
||||
43 bottle
|
||||
44 plate
|
||||
45 wine glass
|
||||
46 cup
|
||||
47 fork
|
||||
48 knife
|
||||
49 spoon
|
||||
50 bowl
|
||||
51 banana
|
||||
52 apple
|
||||
53 sandwich
|
||||
54 orange
|
||||
55 broccoli
|
||||
56 carrot
|
||||
57 hot dog
|
||||
58 pizza
|
||||
59 donut
|
||||
60 cake
|
||||
61 chair
|
||||
62 couch
|
||||
63 potted plant
|
||||
64 bed
|
||||
65 mirror
|
||||
66 dining table
|
||||
67 window
|
||||
68 desk
|
||||
69 toilet
|
||||
70 door
|
||||
71 tv
|
||||
72 laptop
|
||||
73 mouse
|
||||
74 remote
|
||||
75 keyboard
|
||||
76 cell phone
|
||||
77 microwave
|
||||
78 oven
|
||||
79 toaster
|
||||
80 sink
|
||||
81 refrigerator
|
||||
82 blender
|
||||
83 book
|
||||
84 clock
|
||||
85 vase
|
||||
86 scissors
|
||||
87 teddy bear
|
||||
88 hair drier
|
||||
89 toothbrush
|
||||
90 hair brush
|
37
docker/main/rootfs/usr/local/ffmpeg/get_ffmpeg_path.py
Normal file
@@ -0,0 +1,37 @@
|
||||
import json
|
||||
import sys
|
||||
from typing import Any
|
||||
|
||||
from ruamel.yaml import YAML
|
||||
|
||||
sys.path.insert(0, "/opt/frigate")
|
||||
from frigate.const import (
|
||||
DEFAULT_FFMPEG_VERSION,
|
||||
INCLUDED_FFMPEG_VERSIONS,
|
||||
)
|
||||
from frigate.util.config import find_config_file
|
||||
|
||||
sys.path.remove("/opt/frigate")
|
||||
|
||||
yaml = YAML()
|
||||
|
||||
config_file = find_config_file()
|
||||
|
||||
try:
|
||||
with open(config_file) as f:
|
||||
raw_config = f.read()
|
||||
|
||||
if config_file.endswith((".yaml", ".yml")):
|
||||
config: dict[str, Any] = yaml.load(raw_config)
|
||||
elif config_file.endswith(".json"):
|
||||
config: dict[str, Any] = json.loads(raw_config)
|
||||
except FileNotFoundError:
|
||||
config: dict[str, Any] = {}
|
||||
|
||||
path = config.get("ffmpeg", {}).get("path", "default")
|
||||
if path == "default":
|
||||
print(f"/usr/lib/ffmpeg/{DEFAULT_FFMPEG_VERSION}/bin/ffmpeg")
|
||||
elif path in INCLUDED_FFMPEG_VERSIONS:
|
||||
print(f"/usr/lib/ffmpeg/{path}/bin/ffmpeg")
|
||||
else:
|
||||
print(f"{path}/bin/ffmpeg")
|
@@ -4,46 +4,47 @@ import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import yaml
|
||||
from ruamel.yaml import YAML
|
||||
|
||||
sys.path.insert(0, "/opt/frigate")
|
||||
from frigate.const import BIRDSEYE_PIPE # noqa: E402
|
||||
from frigate.ffmpeg_presets import ( # noqa: E402
|
||||
parse_preset_hardware_acceleration_encode,
|
||||
from frigate.const import (
|
||||
BIRDSEYE_PIPE,
|
||||
DEFAULT_FFMPEG_VERSION,
|
||||
INCLUDED_FFMPEG_VERSIONS,
|
||||
LIBAVFORMAT_VERSION_MAJOR,
|
||||
)
|
||||
from frigate.ffmpeg_presets import parse_preset_hardware_acceleration_encode
|
||||
from frigate.util.config import find_config_file
|
||||
|
||||
sys.path.remove("/opt/frigate")
|
||||
|
||||
yaml = YAML()
|
||||
|
||||
FRIGATE_ENV_VARS = {k: v for k, v in os.environ.items() if k.startswith("FRIGATE_")}
|
||||
# read docker secret files as env vars too
|
||||
if os.path.isdir("/run/secrets"):
|
||||
for secret_file in os.listdir("/run/secrets"):
|
||||
if secret_file.startswith("FRIGATE_"):
|
||||
FRIGATE_ENV_VARS[secret_file] = Path(
|
||||
os.path.join("/run/secrets", secret_file)
|
||||
).read_text()
|
||||
FRIGATE_ENV_VARS[secret_file] = (
|
||||
Path(os.path.join("/run/secrets", secret_file)).read_text().strip()
|
||||
)
|
||||
|
||||
config_file = os.environ.get("CONFIG_FILE", "/config/config.yml")
|
||||
|
||||
# Check if we can use .yaml instead of .yml
|
||||
config_file_yaml = config_file.replace(".yml", ".yaml")
|
||||
if os.path.isfile(config_file_yaml):
|
||||
config_file = config_file_yaml
|
||||
config_file = find_config_file()
|
||||
|
||||
try:
|
||||
with open(config_file) as f:
|
||||
raw_config = f.read()
|
||||
|
||||
if config_file.endswith((".yaml", ".yml")):
|
||||
config: dict[str, any] = yaml.safe_load(raw_config)
|
||||
config: dict[str, Any] = yaml.load(raw_config)
|
||||
elif config_file.endswith(".json"):
|
||||
config: dict[str, any] = json.loads(raw_config)
|
||||
config: dict[str, Any] = json.loads(raw_config)
|
||||
except FileNotFoundError:
|
||||
config: dict[str, any] = {}
|
||||
config: dict[str, Any] = {}
|
||||
|
||||
go2rtc_config: dict[str, any] = config.get("go2rtc", {})
|
||||
go2rtc_config: dict[str, Any] = config.get("go2rtc", {})
|
||||
|
||||
# Need to enable CORS for go2rtc so the frigate integration / card work automatically
|
||||
if go2rtc_config.get("api") is None:
|
||||
@@ -53,7 +54,7 @@ elif go2rtc_config["api"].get("origin") is None:
|
||||
|
||||
# Need to set default location for HA config
|
||||
if go2rtc_config.get("hass") is None:
|
||||
go2rtc_config["hass"] = {"config": "/config"}
|
||||
go2rtc_config["hass"] = {"config": "/homeassistant"}
|
||||
|
||||
# we want to ensure that logs are easy to read
|
||||
if go2rtc_config.get("log") is None:
|
||||
@@ -62,59 +63,51 @@ elif go2rtc_config["log"].get("format") is None:
|
||||
go2rtc_config["log"]["format"] = "text"
|
||||
|
||||
# ensure there is a default webrtc config
|
||||
if not go2rtc_config.get("webrtc"):
|
||||
if go2rtc_config.get("webrtc") is None:
|
||||
go2rtc_config["webrtc"] = {}
|
||||
|
||||
# go2rtc should listen on 8555 tcp & udp by default
|
||||
if not go2rtc_config["webrtc"].get("listen"):
|
||||
go2rtc_config["webrtc"]["listen"] = ":8555"
|
||||
|
||||
if not go2rtc_config["webrtc"].get("candidates", []):
|
||||
if go2rtc_config["webrtc"].get("candidates") is None:
|
||||
default_candidates = []
|
||||
# use internal candidate if it was discovered when running through the add-on
|
||||
internal_candidate = os.environ.get(
|
||||
"FRIGATE_GO2RTC_WEBRTC_CANDIDATE_INTERNAL", None
|
||||
)
|
||||
internal_candidate = os.environ.get("FRIGATE_GO2RTC_WEBRTC_CANDIDATE_INTERNAL")
|
||||
if internal_candidate is not None:
|
||||
default_candidates.append(internal_candidate)
|
||||
# should set default stun server so webrtc can work
|
||||
default_candidates.append("stun:8555")
|
||||
|
||||
go2rtc_config["webrtc"] = {"candidates": default_candidates}
|
||||
else:
|
||||
print(
|
||||
"[INFO] Not injecting WebRTC candidates into go2rtc config as it has been set manually",
|
||||
go2rtc_config["webrtc"]["candidates"] = default_candidates
|
||||
|
||||
if go2rtc_config.get("rtsp", {}).get("username") is not None:
|
||||
go2rtc_config["rtsp"]["username"] = go2rtc_config["rtsp"]["username"].format(
|
||||
**FRIGATE_ENV_VARS
|
||||
)
|
||||
|
||||
# sets default RTSP response to be equivalent to ?video=h264,h265&audio=aac
|
||||
# this means user does not need to specify audio codec when using restream
|
||||
# as source for frigate and the integration supports HLS playback
|
||||
if go2rtc_config.get("rtsp") is None:
|
||||
go2rtc_config["rtsp"] = {"default_query": "mp4"}
|
||||
if go2rtc_config.get("rtsp", {}).get("password") is not None:
|
||||
go2rtc_config["rtsp"]["password"] = go2rtc_config["rtsp"]["password"].format(
|
||||
**FRIGATE_ENV_VARS
|
||||
)
|
||||
|
||||
# ensure ffmpeg path is set correctly
|
||||
path = config.get("ffmpeg", {}).get("path", "default")
|
||||
if path == "default":
|
||||
ffmpeg_path = f"/usr/lib/ffmpeg/{DEFAULT_FFMPEG_VERSION}/bin/ffmpeg"
|
||||
elif path in INCLUDED_FFMPEG_VERSIONS:
|
||||
ffmpeg_path = f"/usr/lib/ffmpeg/{path}/bin/ffmpeg"
|
||||
else:
|
||||
if go2rtc_config["rtsp"].get("default_query") is None:
|
||||
go2rtc_config["rtsp"]["default_query"] = "mp4"
|
||||
ffmpeg_path = f"{path}/bin/ffmpeg"
|
||||
|
||||
if go2rtc_config["rtsp"].get("username") is not None:
|
||||
go2rtc_config["rtsp"]["username"] = go2rtc_config["rtsp"]["username"].format(
|
||||
**FRIGATE_ENV_VARS
|
||||
)
|
||||
|
||||
if go2rtc_config["rtsp"].get("password") is not None:
|
||||
go2rtc_config["rtsp"]["password"] = go2rtc_config["rtsp"]["password"].format(
|
||||
**FRIGATE_ENV_VARS
|
||||
)
|
||||
if go2rtc_config.get("ffmpeg") is None:
|
||||
go2rtc_config["ffmpeg"] = {"bin": ffmpeg_path}
|
||||
elif go2rtc_config["ffmpeg"].get("bin") is None:
|
||||
go2rtc_config["ffmpeg"]["bin"] = ffmpeg_path
|
||||
|
||||
# need to replace ffmpeg command when using ffmpeg4
|
||||
if int(os.environ["LIBAVFORMAT_VERSION_MAJOR"]) < 59:
|
||||
if LIBAVFORMAT_VERSION_MAJOR < 59:
|
||||
rtsp_args = "-fflags nobuffer -flags low_delay -stimeout 10000000 -user_agent go2rtc/ffmpeg -rtsp_transport tcp -i {input}"
|
||||
if go2rtc_config.get("ffmpeg") is None:
|
||||
go2rtc_config["ffmpeg"] = {
|
||||
"rtsp": "-fflags nobuffer -flags low_delay -stimeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_transport tcp -i {input}"
|
||||
}
|
||||
go2rtc_config["ffmpeg"] = {"rtsp": rtsp_args}
|
||||
elif go2rtc_config["ffmpeg"].get("rtsp") is None:
|
||||
go2rtc_config["ffmpeg"]["rtsp"] = (
|
||||
"-fflags nobuffer -flags low_delay -stimeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_transport tcp -i {input}"
|
||||
)
|
||||
go2rtc_config["ffmpeg"]["rtsp"] = rtsp_args
|
||||
|
||||
for name in go2rtc_config.get("streams", {}):
|
||||
stream = go2rtc_config["streams"][name]
|
||||
@@ -142,10 +135,10 @@ for name in go2rtc_config.get("streams", {}):
|
||||
|
||||
# add birdseye restream stream if enabled
|
||||
if config.get("birdseye", {}).get("restream", False):
|
||||
birdseye: dict[str, any] = config.get("birdseye")
|
||||
birdseye: dict[str, Any] = config.get("birdseye")
|
||||
|
||||
input = f"-f rawvideo -pix_fmt yuv420p -video_size {birdseye.get('width', 1280)}x{birdseye.get('height', 720)} -r 10 -i {BIRDSEYE_PIPE}"
|
||||
ffmpeg_cmd = f"exec:{parse_preset_hardware_acceleration_encode(config.get('ffmpeg', {}).get('hwaccel_args'), input, '-rtsp_transport tcp -f rtsp {output}')}"
|
||||
ffmpeg_cmd = f"exec:{parse_preset_hardware_acceleration_encode(ffmpeg_path, config.get('ffmpeg', {}).get('hwaccel_args', ''), input, '-rtsp_transport tcp -f rtsp {output}')}"
|
||||
|
||||
if go2rtc_config.get("streams"):
|
||||
go2rtc_config["streams"]["birdseye"] = ffmpeg_cmd
|
||||
|
@@ -1,14 +1,16 @@
|
||||
## Send a subrequest to verify if the user is authenticated and has permission to access the resource.
|
||||
auth_request /auth;
|
||||
|
||||
## Save the upstream metadata response headers from Authelia to variables.
|
||||
## Save the upstream metadata response headers from the auth request to variables
|
||||
auth_request_set $user $upstream_http_remote_user;
|
||||
auth_request_set $role $upstream_http_remote_role;
|
||||
auth_request_set $groups $upstream_http_remote_groups;
|
||||
auth_request_set $name $upstream_http_remote_name;
|
||||
auth_request_set $email $upstream_http_remote_email;
|
||||
|
||||
## Inject the metadata response headers from the variables into the request made to the backend.
|
||||
proxy_set_header Remote-User $user;
|
||||
proxy_set_header Remote-Role $role;
|
||||
proxy_set_header Remote-Groups $groups;
|
||||
proxy_set_header Remote-Email $email;
|
||||
proxy_set_header Remote-Name $name;
|
||||
|
@@ -17,7 +17,9 @@ http {
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
'"$http_user_agent" "$http_x_forwarded_for" '
|
||||
'request_time="$request_time" upstream_response_time="$upstream_response_time"';
|
||||
|
||||
|
||||
access_log /dev/stdout main;
|
||||
|
||||
@@ -30,7 +32,7 @@ http {
|
||||
|
||||
gzip on;
|
||||
gzip_comp_level 6;
|
||||
gzip_types text/plain text/css application/json application/x-javascript application/javascript text/javascript image/svg+xml image/x-icon image/bmp image/png image/gif image/jpeg image/jpg;
|
||||
gzip_types text/plain text/css application/json application/x-javascript application/javascript text/javascript image/svg+xml image/x-icon image/bmp;
|
||||
gzip_proxied no-cache no-store private expired auth;
|
||||
gzip_vary on;
|
||||
|
||||
@@ -59,20 +61,7 @@ http {
|
||||
include go2rtc_upstream.conf;
|
||||
|
||||
server {
|
||||
listen [::]:80 ipv6only=off default_server;
|
||||
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
# intended for external traffic, protected by auth
|
||||
listen [::]:8080 ipv6only=off;
|
||||
# intended for internal traffic, not protected by auth
|
||||
listen [::]:5000 ipv6only=off;
|
||||
|
||||
include tls.conf;
|
||||
include listen.conf;
|
||||
|
||||
# vod settings
|
||||
vod_base_url '';
|
||||
@@ -94,6 +83,9 @@ http {
|
||||
open_file_cache_errors on;
|
||||
aio on;
|
||||
|
||||
# file upload size
|
||||
client_max_body_size 20M;
|
||||
|
||||
# https://github.com/kaltura/nginx-vod-module#vod_open_file_thread_pool
|
||||
vod_open_file_thread_pool default;
|
||||
|
||||
@@ -106,6 +98,7 @@ http {
|
||||
gzip_types application/vnd.apple.mpegurl;
|
||||
|
||||
include auth_location.conf;
|
||||
include base_path.conf;
|
||||
|
||||
location /vod/ {
|
||||
include auth_request.conf;
|
||||
@@ -117,6 +110,16 @@ http {
|
||||
|
||||
add_header Cache-Control "no-store";
|
||||
expires off;
|
||||
|
||||
keepalive_disable safari;
|
||||
|
||||
# vod module returns 502 for non-existent media
|
||||
# https://github.com/kaltura/nginx-vod-module/issues/468
|
||||
error_page 502 =404 /vod-not-found;
|
||||
}
|
||||
|
||||
location = /vod-not-found {
|
||||
return 404;
|
||||
}
|
||||
|
||||
location /stream/ {
|
||||
@@ -141,6 +144,8 @@ http {
|
||||
image/jpeg jpg;
|
||||
}
|
||||
|
||||
expires 7d;
|
||||
add_header Cache-Control "public";
|
||||
autoindex on;
|
||||
root /media/frigate;
|
||||
}
|
||||
@@ -235,7 +240,7 @@ http {
|
||||
|
||||
location ~* /api/.*\.(jpg|jpeg|png|webp|gif)$ {
|
||||
include auth_request.conf;
|
||||
rewrite ^/api/(.*)$ $1 break;
|
||||
rewrite ^/api/(.*)$ /$1 break;
|
||||
proxy_pass http://frigate_api;
|
||||
include proxy.conf;
|
||||
}
|
||||
@@ -297,11 +302,29 @@ http {
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
|
||||
location /locales/ {
|
||||
access_log off;
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
|
||||
location ~ ^/.*-([A-Za-z0-9]+)\.webmanifest$ {
|
||||
access_log off;
|
||||
expires 1y;
|
||||
add_header Cache-Control "public";
|
||||
default_type application/json;
|
||||
proxy_set_header Accept-Encoding "";
|
||||
sub_filter_once off;
|
||||
sub_filter_types application/json;
|
||||
sub_filter '"start_url": "/BASE_PATH/"' '"start_url" : "$http_x_ingress_path/"';
|
||||
sub_filter '"src": "/BASE_PATH/' '"src": "$http_x_ingress_path/';
|
||||
}
|
||||
|
||||
sub_filter 'href="/BASE_PATH/' 'href="$http_x_ingress_path/';
|
||||
sub_filter 'url(/BASE_PATH/' 'url($http_x_ingress_path/';
|
||||
sub_filter '"/BASE_PATH/dist/' '"$http_x_ingress_path/dist/';
|
||||
sub_filter '"/BASE_PATH/js/' '"$http_x_ingress_path/js/';
|
||||
sub_filter '"/BASE_PATH/assets/' '"$http_x_ingress_path/assets/';
|
||||
sub_filter '"/BASE_PATH/locales/' '"$http_x_ingress_path/locales/';
|
||||
sub_filter '"/BASE_PATH/monacoeditorwork/' '"$http_x_ingress_path/assets/';
|
||||
sub_filter 'return"/BASE_PATH/"' 'return window.baseUrl';
|
||||
sub_filter '<body>' '<body><script>window.baseUrl="$http_x_ingress_path/";</script>';
|
||||
|
@@ -1,3 +1,6 @@
|
||||
# Header used to validate reverse proxy trust
|
||||
proxy_set_header X-Proxy-Secret $http_x_proxy_secret;
|
||||
|
||||
# these headers will be copied to the /auth request and are available
|
||||
# to be mapped in the config to Frigate's remote-user header
|
||||
|
||||
@@ -19,4 +22,4 @@ proxy_set_header X-authentik-username $http_x_authentik_username;
|
||||
proxy_set_header X-authentik-groups $http_x_authentik_groups;
|
||||
proxy_set_header X-authentik-email $http_x_authentik_email;
|
||||
proxy_set_header X-authentik-name $http_x_authentik_name;
|
||||
proxy_set_header X-authentik-uid $http_x_authentik_uid;
|
||||
proxy_set_header X-authentik-uid $http_x_authentik_uid;
|
||||
|
@@ -1,24 +0,0 @@
|
||||
keepalive_timeout 70;
|
||||
listen [::]:443 ipv6only=off default_server ssl;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/frigate/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/frigate/privkey.pem;
|
||||
|
||||
# generated 2024-06-01, Mozilla Guideline v5.7, nginx 1.25.3, OpenSSL 1.1.1w, modern configuration, no OCSP
|
||||
# https://ssl-config.mozilla.org/#server=nginx&version=1.25.3&config=modern&openssl=1.1.1w&ocsp=false&guideline=5.7
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
|
||||
ssl_session_tickets off;
|
||||
|
||||
# modern configuration
|
||||
ssl_protocols TLSv1.3;
|
||||
ssl_prefer_server_ciphers off;
|
||||
|
||||
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
|
||||
add_header Strict-Transport-Security "max-age=63072000" always;
|
||||
|
||||
# ACME challenge location
|
||||
location /.well-known/acme-challenge/ {
|
||||
default_type "text/plain";
|
||||
root /etc/letsencrypt/www;
|
||||
}
|
11
docker/main/rootfs/usr/local/nginx/get_base_path.py
Normal file
@@ -0,0 +1,11 @@
|
||||
"""Prints the base path as json to stdout."""
|
||||
|
||||
import json
|
||||
import os
|
||||
from typing import Any
|
||||
|
||||
base_path = os.environ.get("FRIGATE_BASE_PATH", "")
|
||||
|
||||
result: dict[str, Any] = {"base_path": base_path}
|
||||
|
||||
print(json.dumps(result))
|
35
docker/main/rootfs/usr/local/nginx/get_listen_settings.py
Normal file
@@ -0,0 +1,35 @@
|
||||
"""Prints the tls config as json to stdout."""
|
||||
|
||||
import json
|
||||
import sys
|
||||
from typing import Any
|
||||
|
||||
from ruamel.yaml import YAML
|
||||
|
||||
sys.path.insert(0, "/opt/frigate")
|
||||
from frigate.util.config import find_config_file
|
||||
|
||||
sys.path.remove("/opt/frigate")
|
||||
|
||||
yaml = YAML()
|
||||
|
||||
config_file = find_config_file()
|
||||
|
||||
try:
|
||||
with open(config_file) as f:
|
||||
raw_config = f.read()
|
||||
|
||||
if config_file.endswith((".yaml", ".yml")):
|
||||
config: dict[str, Any] = yaml.load(raw_config)
|
||||
elif config_file.endswith(".json"):
|
||||
config: dict[str, Any] = json.loads(raw_config)
|
||||
except FileNotFoundError:
|
||||
config: dict[str, Any] = {}
|
||||
|
||||
tls_config: dict[str, any] = config.get("tls", {"enabled": True})
|
||||
networking_config = config.get("networking", {})
|
||||
ipv6_config = networking_config.get("ipv6", {"enabled": False})
|
||||
|
||||
output = {"tls": tls_config, "ipv6": ipv6_config}
|
||||
|
||||
print(json.dumps(output))
|
@@ -0,0 +1,19 @@
|
||||
{{ if .base_path }}
|
||||
location = {{ .base_path }} {
|
||||
return 302 {{ .base_path }}/;
|
||||
}
|
||||
|
||||
location ^~ {{ .base_path }}/ {
|
||||
# remove base_url from the path before passing upstream
|
||||
rewrite ^{{ .base_path }}/(.*) /$1 break;
|
||||
|
||||
proxy_pass $scheme://127.0.0.1:8971;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Ingress-Path {{ .base_path }};
|
||||
|
||||
access_log off;
|
||||
}
|
||||
{{ end }}
|
45
docker/main/rootfs/usr/local/nginx/templates/listen.gotmpl
Normal file
@@ -0,0 +1,45 @@
|
||||
|
||||
# Internal (IPv4 always; IPv6 optional)
|
||||
listen 5000;
|
||||
{{ if .ipv6 }}{{ if .ipv6.enabled }}listen [::]:5000;{{ end }}{{ end }}
|
||||
|
||||
|
||||
# intended for external traffic, protected by auth
|
||||
{{ if .tls }}
|
||||
{{ if .tls.enabled }}
|
||||
# external HTTPS (IPv4 always; IPv6 optional)
|
||||
listen 8971 ssl;
|
||||
{{ if .ipv6 }}{{ if .ipv6.enabled }}listen [::]:8971 ssl;{{ end }}{{ end }}
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/frigate/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/frigate/privkey.pem;
|
||||
|
||||
# generated 2024-06-01, Mozilla Guideline v5.7, nginx 1.25.3, OpenSSL 1.1.1w, modern configuration, no OCSP
|
||||
# https://ssl-config.mozilla.org/#server=nginx&version=1.25.3&config=modern&openssl=1.1.1w&ocsp=false&guideline=5.7
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
|
||||
ssl_session_tickets off;
|
||||
|
||||
# modern configuration
|
||||
ssl_protocols TLSv1.3;
|
||||
ssl_prefer_server_ciphers off;
|
||||
|
||||
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
|
||||
add_header Strict-Transport-Security "max-age=63072000" always;
|
||||
|
||||
# ACME challenge location
|
||||
location /.well-known/acme-challenge/ {
|
||||
default_type "text/plain";
|
||||
root /etc/letsencrypt/www;
|
||||
}
|
||||
{{ else }}
|
||||
# external HTTP (IPv4 always; IPv6 optional)
|
||||
listen 8971;
|
||||
{{ if .ipv6 }}{{ if .ipv6.enabled }}listen [::]:8971;{{ end }}{{ end }}
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
# (No tls section) default to HTTP (IPv4 always; IPv6 optional)
|
||||
listen 8971;
|
||||
{{ if .ipv6 }}{{ if .ipv6.enabled }}listen [::]:8971;{{ end }}{{ end }}
|
||||
{{ end }}
|
||||
|
47
docker/memryx/user_installation.sh
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/bin/bash
|
||||
set -e # Exit immediately if any command fails
|
||||
set -o pipefail
|
||||
|
||||
echo "Starting MemryX driver and runtime installation..."
|
||||
|
||||
# Detect architecture
|
||||
arch=$(uname -m)
|
||||
|
||||
# Purge existing packages and repo
|
||||
echo "Removing old MemryX installations..."
|
||||
# Remove any holds on MemryX packages (if they exist)
|
||||
sudo apt-mark unhold memx-* mxa-manager || true
|
||||
sudo apt purge -y memx-* mxa-manager || true
|
||||
sudo rm -f /etc/apt/sources.list.d/memryx.list /etc/apt/trusted.gpg.d/memryx.asc
|
||||
|
||||
# Install kernel headers
|
||||
echo "Installing kernel headers for: $(uname -r)"
|
||||
sudo apt update
|
||||
sudo apt install -y dkms linux-headers-$(uname -r)
|
||||
|
||||
# Add MemryX key and repo
|
||||
echo "Adding MemryX GPG key and repository..."
|
||||
wget -qO- https://developer.memryx.com/deb/memryx.asc | sudo tee /etc/apt/trusted.gpg.d/memryx.asc >/dev/null
|
||||
echo 'deb https://developer.memryx.com/deb stable main' | sudo tee /etc/apt/sources.list.d/memryx.list >/dev/null
|
||||
|
||||
# Update and install memx-drivers
|
||||
echo "Installing memx-drivers..."
|
||||
sudo apt update
|
||||
sudo apt install -y memx-drivers
|
||||
|
||||
# ARM-specific board setup
|
||||
if [[ "$arch" == "aarch64" || "$arch" == "arm64" ]]; then
|
||||
echo "Running ARM board setup..."
|
||||
sudo mx_arm_setup
|
||||
fi
|
||||
|
||||
echo -e "\n\n\033[1;31mYOU MUST RESTART YOUR COMPUTER NOW\033[0m\n\n"
|
||||
|
||||
# Install other runtime packages
|
||||
packages=("memx-accl" "mxa-manager")
|
||||
for pkg in "${packages[@]}"; do
|
||||
echo "Installing $pkg..."
|
||||
sudo apt install -y "$pkg"
|
||||
done
|
||||
|
||||
echo "MemryX installation complete!"
|
20
docker/rockchip/COCO/coco_subset_20.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
./subset/000000005001.jpg
|
||||
./subset/000000038829.jpg
|
||||
./subset/000000052891.jpg
|
||||
./subset/000000075612.jpg
|
||||
./subset/000000098261.jpg
|
||||
./subset/000000181542.jpg
|
||||
./subset/000000215245.jpg
|
||||
./subset/000000277005.jpg
|
||||
./subset/000000288685.jpg
|
||||
./subset/000000301421.jpg
|
||||
./subset/000000334371.jpg
|
||||
./subset/000000348481.jpg
|
||||
./subset/000000373353.jpg
|
||||
./subset/000000397681.jpg
|
||||
./subset/000000414673.jpg
|
||||
./subset/000000419312.jpg
|
||||
./subset/000000465822.jpg
|
||||
./subset/000000475732.jpg
|
||||
./subset/000000559707.jpg
|
||||
./subset/000000574315.jpg
|
BIN
docker/rockchip/COCO/subset/000000005001.jpg
Normal file
After Width: | Height: | Size: 207 KiB |
BIN
docker/rockchip/COCO/subset/000000038829.jpg
Normal file
After Width: | Height: | Size: 209 KiB |
BIN
docker/rockchip/COCO/subset/000000052891.jpg
Normal file
After Width: | Height: | Size: 150 KiB |
BIN
docker/rockchip/COCO/subset/000000075612.jpg
Normal file
After Width: | Height: | Size: 102 KiB |
BIN
docker/rockchip/COCO/subset/000000098261.jpg
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
docker/rockchip/COCO/subset/000000181542.jpg
Normal file
After Width: | Height: | Size: 201 KiB |
BIN
docker/rockchip/COCO/subset/000000215245.jpg
Normal file
After Width: | Height: | Size: 233 KiB |
BIN
docker/rockchip/COCO/subset/000000277005.jpg
Normal file
After Width: | Height: | Size: 242 KiB |
BIN
docker/rockchip/COCO/subset/000000288685.jpg
Normal file
After Width: | Height: | Size: 230 KiB |
BIN
docker/rockchip/COCO/subset/000000301421.jpg
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
docker/rockchip/COCO/subset/000000334371.jpg
Normal file
After Width: | Height: | Size: 136 KiB |
BIN
docker/rockchip/COCO/subset/000000348481.jpg
Normal file
After Width: | Height: | Size: 113 KiB |
BIN
docker/rockchip/COCO/subset/000000373353.jpg
Normal file
After Width: | Height: | Size: 281 KiB |
BIN
docker/rockchip/COCO/subset/000000397681.jpg
Normal file
After Width: | Height: | Size: 272 KiB |
BIN
docker/rockchip/COCO/subset/000000414673.jpg
Normal file
After Width: | Height: | Size: 152 KiB |
BIN
docker/rockchip/COCO/subset/000000419312.jpg
Normal file
After Width: | Height: | Size: 166 KiB |
BIN
docker/rockchip/COCO/subset/000000465822.jpg
Normal file
After Width: | Height: | Size: 109 KiB |
BIN
docker/rockchip/COCO/subset/000000475732.jpg
Normal file
After Width: | Height: | Size: 103 KiB |
BIN
docker/rockchip/COCO/subset/000000559707.jpg
Normal file
After Width: | Height: | Size: 203 KiB |
BIN
docker/rockchip/COCO/subset/000000574315.jpg
Normal file
After Width: | Height: | Size: 110 KiB |
@@ -3,24 +3,36 @@
|
||||
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Globally set pip break-system-packages option to avoid having to specify it every time
|
||||
ARG PIP_BREAK_SYSTEM_PACKAGES=1
|
||||
|
||||
FROM wheels as rk-wheels
|
||||
COPY docker/main/requirements-wheels.txt /requirements-wheels.txt
|
||||
COPY docker/rockchip/requirements-wheels-rk.txt /requirements-wheels-rk.txt
|
||||
RUN sed -i "/https:\/\//d" /requirements-wheels.txt
|
||||
RUN pip3 wheel --wheel-dir=/rk-wheels -c /requirements-wheels.txt -r /requirements-wheels-rk.txt
|
||||
RUN sed -i "/onnxruntime/d" /requirements-wheels.txt
|
||||
RUN sed -i '/\[.*\]/d' /requirements-wheels.txt \
|
||||
&& pip3 wheel --wheel-dir=/rk-wheels -c /requirements-wheels.txt -r /requirements-wheels-rk.txt
|
||||
RUN rm -rf /rk-wheels/opencv_python-*
|
||||
RUN rm -rf /rk-wheels/torch-*
|
||||
|
||||
FROM deps AS rk-frigate
|
||||
ARG TARGETARCH
|
||||
ARG PIP_BREAK_SYSTEM_PACKAGES
|
||||
|
||||
RUN --mount=type=bind,from=rk-wheels,source=/rk-wheels,target=/deps/rk-wheels \
|
||||
pip3 install -U /deps/rk-wheels/*.whl
|
||||
pip3 install --no-deps -U /deps/rk-wheels/*.whl
|
||||
|
||||
WORKDIR /opt/frigate/
|
||||
COPY --from=rootfs / /
|
||||
COPY docker/rockchip/COCO /COCO
|
||||
COPY docker/rockchip/conv2rknn.py /opt/conv2rknn.py
|
||||
|
||||
ADD https://github.com/MarcA711/rknn-toolkit2/releases/download/v2.0.0/librknnrt.so /usr/lib/
|
||||
ADD https://github.com/MarcA711/rknn-toolkit2/releases/download/v2.3.2/librknnrt.so /usr/lib/
|
||||
|
||||
RUN rm -rf /usr/lib/btbn-ffmpeg/bin/ffmpeg
|
||||
RUN rm -rf /usr/lib/btbn-ffmpeg/bin/ffprobe
|
||||
ADD --chmod=111 https://github.com/MarcA711/Rockchip-FFmpeg-Builds/releases/download/6.1-3/ffmpeg /usr/lib/btbn-ffmpeg/bin/
|
||||
ADD --chmod=111 https://github.com/MarcA711/Rockchip-FFmpeg-Builds/releases/download/6.1-3/ffprobe /usr/lib/btbn-ffmpeg/bin/
|
||||
ADD --chmod=111 https://github.com/MarcA711/Rockchip-FFmpeg-Builds/releases/download/6.1-11/ffmpeg /usr/lib/ffmpeg/6.0/bin/
|
||||
ADD --chmod=111 https://github.com/MarcA711/Rockchip-FFmpeg-Builds/releases/download/6.1-11/ffprobe /usr/lib/ffmpeg/6.0/bin/
|
||||
ADD --chmod=111 https://github.com/MarcA711/Rockchip-FFmpeg-Builds/releases/download/7.1-1/ffmpeg /usr/lib/ffmpeg/7.0/bin/
|
||||
ADD --chmod=111 https://github.com/MarcA711/Rockchip-FFmpeg-Builds/releases/download/7.1-1/ffprobe /usr/lib/ffmpeg/7.0/bin/
|
||||
ENV DEFAULT_FFMPEG_VERSION="6.0"
|
||||
ENV INCLUDED_FFMPEG_VERSIONS="${DEFAULT_FFMPEG_VERSION}:${INCLUDED_FFMPEG_VERSIONS}"
|
||||
|
82
docker/rockchip/conv2rknn.py
Normal file
@@ -0,0 +1,82 @@
|
||||
import os
|
||||
|
||||
import rknn
|
||||
import yaml
|
||||
from rknn.api import RKNN
|
||||
|
||||
try:
|
||||
with open(rknn.__path__[0] + "/VERSION") as file:
|
||||
tk_version = file.read().strip()
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
try:
|
||||
with open("/config/conv2rknn.yaml", "r") as config_file:
|
||||
configuration = yaml.safe_load(config_file)
|
||||
except FileNotFoundError:
|
||||
raise Exception("Please place a config file at /config/conv2rknn.yaml")
|
||||
|
||||
if configuration["config"] != None:
|
||||
rknn_config = configuration["config"]
|
||||
else:
|
||||
rknn_config = {}
|
||||
|
||||
if not os.path.isdir("/config/model_cache/rknn_cache/onnx"):
|
||||
raise Exception(
|
||||
"Place the onnx models you want to convert to rknn format in /config/model_cache/rknn_cache/onnx"
|
||||
)
|
||||
|
||||
if "soc" not in configuration:
|
||||
try:
|
||||
with open("/proc/device-tree/compatible") as file:
|
||||
soc = file.read().split(",")[-1].strip("\x00")
|
||||
except FileNotFoundError:
|
||||
raise Exception("Make sure to run docker in privileged mode.")
|
||||
|
||||
configuration["soc"] = [
|
||||
soc,
|
||||
]
|
||||
|
||||
if "quantization" not in configuration:
|
||||
configuration["quantization"] = False
|
||||
|
||||
if "output_name" not in configuration:
|
||||
configuration["output_name"] = "{{input_basename}}"
|
||||
|
||||
for input_filename in os.listdir("/config/model_cache/rknn_cache/onnx"):
|
||||
for soc in configuration["soc"]:
|
||||
quant = "i8" if configuration["quantization"] else "fp16"
|
||||
|
||||
input_path = "/config/model_cache/rknn_cache/onnx/" + input_filename
|
||||
input_basename = input_filename[: input_filename.rfind(".")]
|
||||
|
||||
output_filename = (
|
||||
configuration["output_name"].format(
|
||||
quant=quant,
|
||||
input_basename=input_basename,
|
||||
soc=soc,
|
||||
tk_version=tk_version,
|
||||
)
|
||||
+ ".rknn"
|
||||
)
|
||||
output_path = "/config/model_cache/rknn_cache/" + output_filename
|
||||
|
||||
rknn_config["target_platform"] = soc
|
||||
|
||||
rknn = RKNN(verbose=True)
|
||||
rknn.config(**rknn_config)
|
||||
|
||||
if rknn.load_onnx(model=input_path) != 0:
|
||||
raise Exception("Error loading model.")
|
||||
|
||||
if (
|
||||
rknn.build(
|
||||
do_quantization=configuration["quantization"],
|
||||
dataset="/COCO/coco_subset_20.txt",
|
||||
)
|
||||
!= 0
|
||||
):
|
||||
raise Exception("Error building model.")
|
||||
|
||||
if rknn.export_rknn(output_path) != 0:
|
||||
raise Exception("Error exporting rknn model.")
|
@@ -1 +1,2 @@
|
||||
rknn-toolkit-lite2 @ https://github.com/MarcA711/rknn-toolkit2/releases/download/v2.0.0/rknn_toolkit_lite2-2.0.0b0-cp39-cp39-linux_aarch64.whl
|
||||
rknn-toolkit2 == 2.3.2
|
||||
rknn-toolkit-lite2 == 2.3.2
|
@@ -1,10 +1,15 @@
|
||||
BOARDS += rk
|
||||
|
||||
local-rk: version
|
||||
docker buildx bake --load --file=docker/rockchip/rk.hcl --set rk.tags=frigate:latest-rk rk
|
||||
docker buildx bake --file=docker/rockchip/rk.hcl rk \
|
||||
--set rk.tags=frigate:latest-rk \
|
||||
--load
|
||||
|
||||
build-rk: version
|
||||
docker buildx bake --file=docker/rockchip/rk.hcl --set rk.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-rk rk
|
||||
docker buildx bake --file=docker/rockchip/rk.hcl rk \
|
||||
--set rk.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-rk
|
||||
|
||||
push-rk: build-rk
|
||||
docker buildx bake --push --file=docker/rockchip/rk.hcl --set rk.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-rk rk
|
||||
docker buildx bake --file=docker/rockchip/rk.hcl rk \
|
||||
--set rk.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-rk \
|
||||
--push
|
@@ -2,74 +2,53 @@
|
||||
|
||||
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG ROCM=5.7.3
|
||||
ARG ROCM=1
|
||||
ARG AMDGPU=gfx900
|
||||
ARG HSA_OVERRIDE_GFX_VERSION
|
||||
ARG HSA_OVERRIDE
|
||||
|
||||
#######################################################################
|
||||
FROM ubuntu:focal as rocm
|
||||
FROM wget AS rocm
|
||||
|
||||
ARG ROCM
|
||||
ARG AMDGPU
|
||||
|
||||
RUN apt-get update && apt-get -y upgrade
|
||||
RUN apt-get -y install gnupg wget
|
||||
|
||||
RUN mkdir --parents --mode=0755 /etc/apt/keyrings
|
||||
|
||||
RUN wget https://repo.radeon.com/rocm/rocm.gpg.key -O - | gpg --dearmor | tee /etc/apt/keyrings/rocm.gpg > /dev/null
|
||||
COPY docker/rocm/rocm.list /etc/apt/sources.list.d/
|
||||
COPY docker/rocm/rocm-pin-600 /etc/apt/preferences.d/
|
||||
|
||||
RUN apt-get update
|
||||
|
||||
RUN apt-get -y install --no-install-recommends migraphx
|
||||
RUN apt-get -y install --no-install-recommends migraphx-dev
|
||||
RUN apt update -qq && \
|
||||
apt install -y wget gpg && \
|
||||
wget -O rocm.deb https://repo.radeon.com/amdgpu-install/7.0.1/ubuntu/jammy/amdgpu-install_7.0.1.70001-1_all.deb && \
|
||||
apt install -y ./rocm.deb && \
|
||||
apt update && \
|
||||
apt install -qq -y rocm
|
||||
|
||||
RUN mkdir -p /opt/rocm-dist/opt/rocm-$ROCM/lib
|
||||
RUN cd /opt/rocm-$ROCM/lib && cp -dpr libMIOpen*.so* libamd*.so* libhip*.so* libhsa*.so* libmigraphx*.so* librocm*.so* librocblas*.so* /opt/rocm-dist/opt/rocm-$ROCM/lib/
|
||||
RUN cd /opt/rocm-$ROCM/lib && \
|
||||
cp -dpr libMIOpen*.so* libamd*.so* libhip*.so* libhsa*.so* libmigraphx*.so* librocm*.so* librocblas*.so* libroctracer*.so* librocsolver*.so* librocfft*.so* librocprofiler*.so* libroctx*.so* librocroller.so* /opt/rocm-dist/opt/rocm-$ROCM/lib/ && \
|
||||
mkdir -p /opt/rocm-dist/opt/rocm-$ROCM/lib/migraphx/lib && \
|
||||
cp -dpr migraphx/lib/* /opt/rocm-dist/opt/rocm-$ROCM/lib/migraphx/lib
|
||||
RUN cd /opt/rocm-dist/opt/ && ln -s rocm-$ROCM rocm
|
||||
|
||||
RUN mkdir -p /opt/rocm-dist/etc/ld.so.conf.d/
|
||||
RUN echo /opt/rocm/lib|tee /opt/rocm-dist/etc/ld.so.conf.d/rocm.conf
|
||||
|
||||
#######################################################################
|
||||
FROM --platform=linux/amd64 debian:11 as debian-base
|
||||
|
||||
RUN apt-get update && apt-get -y upgrade
|
||||
RUN apt-get -y install --no-install-recommends libelf1 libdrm2 libdrm-amdgpu1 libnuma1 kmod
|
||||
|
||||
RUN apt-get -y install python3
|
||||
|
||||
#######################################################################
|
||||
# ROCm does not come with migraphx wrappers for python 3.9, so we build it here
|
||||
FROM debian-base as debian-build
|
||||
|
||||
ARG ROCM
|
||||
|
||||
COPY --from=rocm /opt/rocm-$ROCM /opt/rocm-$ROCM
|
||||
RUN ln -s /opt/rocm-$ROCM /opt/rocm
|
||||
|
||||
RUN apt-get -y install g++ cmake
|
||||
RUN apt-get -y install python3-pybind11 python3.9-distutils python3-dev
|
||||
|
||||
WORKDIR /opt/build
|
||||
|
||||
COPY docker/rocm/migraphx .
|
||||
|
||||
RUN mkdir build && cd build && cmake .. && make install
|
||||
|
||||
#######################################################################
|
||||
FROM deps AS deps-prelim
|
||||
|
||||
# need this to install libnuma1
|
||||
RUN apt-get update
|
||||
# no ugprade?!?!
|
||||
RUN apt-get -y install libnuma1
|
||||
COPY docker/rocm/debian-backports.sources /etc/apt/sources.list.d/debian-backports.sources
|
||||
RUN apt-get update && \
|
||||
apt-get install -y libnuma1 && \
|
||||
apt-get install -qq -y -t bookworm-backports mesa-va-drivers mesa-vulkan-drivers
|
||||
|
||||
WORKDIR /opt/frigate/
|
||||
WORKDIR /opt/frigate
|
||||
COPY --from=rootfs / /
|
||||
COPY docker/rocm/rootfs/ /
|
||||
|
||||
RUN wget -q https://bootstrap.pypa.io/get-pip.py -O get-pip.py \
|
||||
&& sed -i 's/args.append("setuptools")/args.append("setuptools==77.0.3")/' get-pip.py \
|
||||
&& python3 get-pip.py "pip" --break-system-packages
|
||||
RUN python3 -m pip config set global.break-system-packages true
|
||||
|
||||
COPY docker/rocm/requirements-wheels-rocm.txt /requirements.txt
|
||||
RUN pip3 uninstall -y onnxruntime \
|
||||
&& pip3 install -r /requirements.txt
|
||||
|
||||
#######################################################################
|
||||
FROM scratch AS rocm-dist
|
||||
@@ -79,14 +58,16 @@ ARG AMDGPU
|
||||
|
||||
COPY --from=rocm /opt/rocm-$ROCM/bin/rocminfo /opt/rocm-$ROCM/bin/migraphx-driver /opt/rocm-$ROCM/bin/
|
||||
COPY --from=rocm /opt/rocm-$ROCM/share/miopen/db/*$AMDGPU* /opt/rocm-$ROCM/share/miopen/db/
|
||||
COPY --from=rocm /opt/rocm-$ROCM/share/miopen/db/*gfx908* /opt/rocm-$ROCM/share/miopen/db/
|
||||
COPY --from=rocm /opt/rocm-$ROCM/lib/rocblas/library/*$AMDGPU* /opt/rocm-$ROCM/lib/rocblas/library/
|
||||
COPY --from=rocm /opt/rocm-dist/ /
|
||||
COPY --from=debian-build /opt/rocm/lib/migraphx.cpython-39-x86_64-linux-gnu.so /opt/rocm-$ROCM/lib/
|
||||
|
||||
#######################################################################
|
||||
FROM deps-prelim AS rocm-prelim-hsa-override0
|
||||
|
||||
ENV HSA_ENABLE_SDMA=0
|
||||
ENV MIGRAPHX_DISABLE_MIOPEN_FUSION=1
|
||||
ENV MIGRAPHX_DISABLE_SCHEDULE_PASS=1
|
||||
ENV MIGRAPHX_DISABLE_REDUCE_FUSION=1
|
||||
ENV MIGRAPHX_ENABLE_HIPRTC_WORKAROUNDS=1
|
||||
|
||||
COPY --from=rocm-dist / /
|
||||
|
||||
@@ -101,6 +82,3 @@ ENV HSA_OVERRIDE_GFX_VERSION=$HSA_OVERRIDE_GFX_VERSION
|
||||
#######################################################################
|
||||
FROM rocm-prelim-hsa-override$HSA_OVERRIDE as rocm-deps
|
||||
|
||||
# Request yolov8 download at startup
|
||||
ENV DOWNLOAD_YOLOV8=1
|
||||
|
||||
|
6
docker/rocm/debian-backports.sources
Normal file
@@ -0,0 +1,6 @@
|
||||
Types: deb
|
||||
URIs: http://deb.debian.org/debian
|
||||
Suites: bookworm-backports
|
||||
Components: main
|
||||
Enabled: yes
|
||||
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
|
@@ -1,26 +0,0 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
|
||||
project(migraphx_py)
|
||||
|
||||
include_directories(/opt/rocm/include)
|
||||
|
||||
find_package(pybind11 REQUIRED)
|
||||
pybind11_add_module(migraphx migraphx_py.cpp)
|
||||
|
||||
target_link_libraries(migraphx PRIVATE /opt/rocm/lib/libmigraphx.so /opt/rocm/lib/libmigraphx_tf.so /opt/rocm/lib/libmigraphx_onnx.so)
|
||||
|
||||
install(TARGETS migraphx
|
||||
COMPONENT python
|
||||
LIBRARY DESTINATION /opt/rocm/lib
|
||||
)
|
@@ -1,582 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/numpy.h>
|
||||
#include <migraphx/program.hpp>
|
||||
#include <migraphx/instruction_ref.hpp>
|
||||
#include <migraphx/operation.hpp>
|
||||
#include <migraphx/quantization.hpp>
|
||||
#include <migraphx/generate.hpp>
|
||||
#include <migraphx/instruction.hpp>
|
||||
#include <migraphx/ref/target.hpp>
|
||||
#include <migraphx/stringutils.hpp>
|
||||
#include <migraphx/tf.hpp>
|
||||
#include <migraphx/onnx.hpp>
|
||||
#include <migraphx/load_save.hpp>
|
||||
#include <migraphx/register_target.hpp>
|
||||
#include <migraphx/json.hpp>
|
||||
#include <migraphx/make_op.hpp>
|
||||
#include <migraphx/op/common.hpp>
|
||||
|
||||
#ifdef HAVE_GPU
|
||||
#include <migraphx/gpu/hip.hpp>
|
||||
#endif
|
||||
|
||||
using half = half_float::half;
|
||||
namespace py = pybind11;
|
||||
|
||||
#ifdef __clang__
|
||||
#define MIGRAPHX_PUSH_UNUSED_WARNING \
|
||||
_Pragma("clang diagnostic push") \
|
||||
_Pragma("clang diagnostic ignored \"-Wused-but-marked-unused\"")
|
||||
#define MIGRAPHX_POP_WARNING _Pragma("clang diagnostic pop")
|
||||
#else
|
||||
#define MIGRAPHX_PUSH_UNUSED_WARNING
|
||||
#define MIGRAPHX_POP_WARNING
|
||||
#endif
|
||||
#define MIGRAPHX_PYBIND11_MODULE(...) \
|
||||
MIGRAPHX_PUSH_UNUSED_WARNING \
|
||||
PYBIND11_MODULE(__VA_ARGS__) \
|
||||
MIGRAPHX_POP_WARNING
|
||||
|
||||
#define MIGRAPHX_PYTHON_GENERATE_SHAPE_ENUM(x, t) .value(#x, migraphx::shape::type_t::x)
|
||||
namespace migraphx {
|
||||
|
||||
migraphx::value to_value(py::kwargs kwargs);
|
||||
migraphx::value to_value(py::list lst);
|
||||
|
||||
template <class T, class F>
|
||||
void visit_py(T x, F f)
|
||||
{
|
||||
if(py::isinstance<py::kwargs>(x))
|
||||
{
|
||||
f(to_value(x.template cast<py::kwargs>()));
|
||||
}
|
||||
else if(py::isinstance<py::list>(x))
|
||||
{
|
||||
f(to_value(x.template cast<py::list>()));
|
||||
}
|
||||
else if(py::isinstance<py::bool_>(x))
|
||||
{
|
||||
f(x.template cast<bool>());
|
||||
}
|
||||
else if(py::isinstance<py::int_>(x) or py::hasattr(x, "__index__"))
|
||||
{
|
||||
f(x.template cast<int>());
|
||||
}
|
||||
else if(py::isinstance<py::float_>(x))
|
||||
{
|
||||
f(x.template cast<float>());
|
||||
}
|
||||
else if(py::isinstance<py::str>(x))
|
||||
{
|
||||
f(x.template cast<std::string>());
|
||||
}
|
||||
else if(py::isinstance<migraphx::shape::dynamic_dimension>(x))
|
||||
{
|
||||
f(migraphx::to_value(x.template cast<migraphx::shape::dynamic_dimension>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
MIGRAPHX_THROW("VISIT_PY: Unsupported data type!");
|
||||
}
|
||||
}
|
||||
|
||||
migraphx::value to_value(py::list lst)
|
||||
{
|
||||
migraphx::value v = migraphx::value::array{};
|
||||
for(auto val : lst)
|
||||
{
|
||||
visit_py(val, [&](auto py_val) { v.push_back(py_val); });
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
migraphx::value to_value(py::kwargs kwargs)
|
||||
{
|
||||
migraphx::value v = migraphx::value::object{};
|
||||
|
||||
for(auto arg : kwargs)
|
||||
{
|
||||
auto&& key = py::str(arg.first);
|
||||
auto&& val = arg.second;
|
||||
visit_py(val, [&](auto py_val) { v[key] = py_val; });
|
||||
}
|
||||
return v;
|
||||
}
|
||||
} // namespace migraphx
|
||||
|
||||
namespace pybind11 {
|
||||
namespace detail {
|
||||
|
||||
template <>
|
||||
struct npy_format_descriptor<half>
|
||||
{
|
||||
static std::string format()
|
||||
{
|
||||
// following: https://docs.python.org/3/library/struct.html#format-characters
|
||||
return "e";
|
||||
}
|
||||
static constexpr auto name() { return _("half"); }
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace pybind11
|
||||
|
||||
template <class F>
|
||||
void visit_type(const migraphx::shape& s, F f)
|
||||
{
|
||||
s.visit_type(f);
|
||||
}
|
||||
|
||||
template <class T, class F>
|
||||
void visit(const migraphx::raw_data<T>& x, F f)
|
||||
{
|
||||
x.visit(f);
|
||||
}
|
||||
|
||||
template <class F>
|
||||
void visit_types(F f)
|
||||
{
|
||||
migraphx::shape::visit_types(f);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
py::buffer_info to_buffer_info(T& x)
|
||||
{
|
||||
migraphx::shape s = x.get_shape();
|
||||
assert(s.type() != migraphx::shape::tuple_type);
|
||||
if(s.dynamic())
|
||||
MIGRAPHX_THROW("MIGRAPHX PYTHON: dynamic shape argument passed to to_buffer_info");
|
||||
auto strides = s.strides();
|
||||
std::transform(
|
||||
strides.begin(), strides.end(), strides.begin(), [&](auto i) { return i * s.type_size(); });
|
||||
py::buffer_info b;
|
||||
visit_type(s, [&](auto as) {
|
||||
// migraphx use int8_t data to store bool type, we need to
|
||||
// explicitly specify the data type as bool for python
|
||||
if(s.type() == migraphx::shape::bool_type)
|
||||
{
|
||||
b = py::buffer_info(x.data(),
|
||||
as.size(),
|
||||
py::format_descriptor<bool>::format(),
|
||||
s.ndim(),
|
||||
s.lens(),
|
||||
strides);
|
||||
}
|
||||
else
|
||||
{
|
||||
b = py::buffer_info(x.data(),
|
||||
as.size(),
|
||||
py::format_descriptor<decltype(as())>::format(),
|
||||
s.ndim(),
|
||||
s.lens(),
|
||||
strides);
|
||||
}
|
||||
});
|
||||
return b;
|
||||
}
|
||||
|
||||
migraphx::shape to_shape(const py::buffer_info& info)
|
||||
{
|
||||
migraphx::shape::type_t t;
|
||||
std::size_t n = 0;
|
||||
visit_types([&](auto as) {
|
||||
if(info.format == py::format_descriptor<decltype(as())>::format() or
|
||||
(info.format == "l" and py::format_descriptor<decltype(as())>::format() == "q") or
|
||||
(info.format == "L" and py::format_descriptor<decltype(as())>::format() == "Q"))
|
||||
{
|
||||
t = as.type_enum();
|
||||
n = sizeof(as());
|
||||
}
|
||||
else if(info.format == "?" and py::format_descriptor<decltype(as())>::format() == "b")
|
||||
{
|
||||
t = migraphx::shape::bool_type;
|
||||
n = sizeof(bool);
|
||||
}
|
||||
});
|
||||
|
||||
if(n == 0)
|
||||
{
|
||||
MIGRAPHX_THROW("MIGRAPHX PYTHON: Unsupported data type " + info.format);
|
||||
}
|
||||
|
||||
auto strides = info.strides;
|
||||
std::transform(strides.begin(), strides.end(), strides.begin(), [&](auto i) -> std::size_t {
|
||||
return n > 0 ? i / n : 0;
|
||||
});
|
||||
|
||||
// scalar support
|
||||
if(info.shape.empty())
|
||||
{
|
||||
return migraphx::shape{t};
|
||||
}
|
||||
else
|
||||
{
|
||||
return migraphx::shape{t, info.shape, strides};
|
||||
}
|
||||
}
|
||||
|
||||
MIGRAPHX_PYBIND11_MODULE(migraphx, m)
|
||||
{
|
||||
py::class_<migraphx::shape> shape_cls(m, "shape");
|
||||
shape_cls
|
||||
.def(py::init([](py::kwargs kwargs) {
|
||||
auto v = migraphx::to_value(kwargs);
|
||||
auto t = migraphx::shape::parse_type(v.get("type", "float"));
|
||||
if(v.contains("dyn_dims"))
|
||||
{
|
||||
auto dyn_dims =
|
||||
migraphx::from_value<std::vector<migraphx::shape::dynamic_dimension>>(
|
||||
v.at("dyn_dims"));
|
||||
return migraphx::shape(t, dyn_dims);
|
||||
}
|
||||
auto lens = v.get<std::size_t>("lens", {1});
|
||||
if(v.contains("strides"))
|
||||
return migraphx::shape(t, lens, v.at("strides").to_vector<std::size_t>());
|
||||
else
|
||||
return migraphx::shape(t, lens);
|
||||
}))
|
||||
.def("type", &migraphx::shape::type)
|
||||
.def("lens", &migraphx::shape::lens)
|
||||
.def("strides", &migraphx::shape::strides)
|
||||
.def("ndim", &migraphx::shape::ndim)
|
||||
.def("elements", &migraphx::shape::elements)
|
||||
.def("bytes", &migraphx::shape::bytes)
|
||||
.def("type_string", &migraphx::shape::type_string)
|
||||
.def("type_size", &migraphx::shape::type_size)
|
||||
.def("dyn_dims", &migraphx::shape::dyn_dims)
|
||||
.def("packed", &migraphx::shape::packed)
|
||||
.def("transposed", &migraphx::shape::transposed)
|
||||
.def("broadcasted", &migraphx::shape::broadcasted)
|
||||
.def("standard", &migraphx::shape::standard)
|
||||
.def("scalar", &migraphx::shape::scalar)
|
||||
.def("dynamic", &migraphx::shape::dynamic)
|
||||
.def("__eq__", std::equal_to<migraphx::shape>{})
|
||||
.def("__ne__", std::not_equal_to<migraphx::shape>{})
|
||||
.def("__repr__", [](const migraphx::shape& s) { return migraphx::to_string(s); });
|
||||
|
||||
py::enum_<migraphx::shape::type_t>(shape_cls, "type_t")
|
||||
MIGRAPHX_SHAPE_VISIT_TYPES(MIGRAPHX_PYTHON_GENERATE_SHAPE_ENUM);
|
||||
|
||||
py::class_<migraphx::shape::dynamic_dimension>(shape_cls, "dynamic_dimension")
|
||||
.def(py::init<>())
|
||||
.def(py::init<std::size_t, std::size_t>())
|
||||
.def(py::init<std::size_t, std::size_t, std::set<std::size_t>>())
|
||||
.def_readwrite("min", &migraphx::shape::dynamic_dimension::min)
|
||||
.def_readwrite("max", &migraphx::shape::dynamic_dimension::max)
|
||||
.def_readwrite("optimals", &migraphx::shape::dynamic_dimension::optimals)
|
||||
.def("is_fixed", &migraphx::shape::dynamic_dimension::is_fixed);
|
||||
|
||||
py::class_<migraphx::argument>(m, "argument", py::buffer_protocol())
|
||||
.def_buffer([](migraphx::argument& x) -> py::buffer_info { return to_buffer_info(x); })
|
||||
.def(py::init([](py::buffer b) {
|
||||
py::buffer_info info = b.request();
|
||||
return migraphx::argument(to_shape(info), info.ptr);
|
||||
}))
|
||||
.def("get_shape", &migraphx::argument::get_shape)
|
||||
.def("data_ptr",
|
||||
[](migraphx::argument& x) { return reinterpret_cast<std::uintptr_t>(x.data()); })
|
||||
.def("tolist",
|
||||
[](migraphx::argument& x) {
|
||||
py::list l{x.get_shape().elements()};
|
||||
visit(x, [&](auto data) { l = py::cast(data.to_vector()); });
|
||||
return l;
|
||||
})
|
||||
.def("__eq__", std::equal_to<migraphx::argument>{})
|
||||
.def("__ne__", std::not_equal_to<migraphx::argument>{})
|
||||
.def("__repr__", [](const migraphx::argument& x) { return migraphx::to_string(x); });
|
||||
|
||||
py::class_<migraphx::target>(m, "target");
|
||||
|
||||
py::class_<migraphx::instruction_ref>(m, "instruction_ref")
|
||||
.def("shape", [](migraphx::instruction_ref i) { return i->get_shape(); })
|
||||
.def("op", [](migraphx::instruction_ref i) { return i->get_operator(); });
|
||||
|
||||
py::class_<migraphx::module, std::unique_ptr<migraphx::module, py::nodelete>>(m, "module")
|
||||
.def("print", [](const migraphx::module& mm) { std::cout << mm << std::endl; })
|
||||
.def(
|
||||
"add_instruction",
|
||||
[](migraphx::module& mm,
|
||||
const migraphx::operation& op,
|
||||
std::vector<migraphx::instruction_ref>& args,
|
||||
std::vector<migraphx::module*>& mod_args) {
|
||||
return mm.add_instruction(op, args, mod_args);
|
||||
},
|
||||
py::arg("op"),
|
||||
py::arg("args"),
|
||||
py::arg("mod_args") = std::vector<migraphx::module*>{})
|
||||
.def(
|
||||
"add_literal",
|
||||
[](migraphx::module& mm, py::buffer data) {
|
||||
py::buffer_info info = data.request();
|
||||
auto literal_shape = to_shape(info);
|
||||
return mm.add_literal(literal_shape, reinterpret_cast<char*>(info.ptr));
|
||||
},
|
||||
py::arg("data"))
|
||||
.def(
|
||||
"add_parameter",
|
||||
[](migraphx::module& mm, const std::string& name, const migraphx::shape shape) {
|
||||
return mm.add_parameter(name, shape);
|
||||
},
|
||||
py::arg("name"),
|
||||
py::arg("shape"))
|
||||
.def(
|
||||
"add_return",
|
||||
[](migraphx::module& mm, std::vector<migraphx::instruction_ref>& args) {
|
||||
return mm.add_return(args);
|
||||
},
|
||||
py::arg("args"))
|
||||
.def("__repr__", [](const migraphx::module& mm) { return migraphx::to_string(mm); });
|
||||
|
||||
py::class_<migraphx::program>(m, "program")
|
||||
.def(py::init([]() { return migraphx::program(); }))
|
||||
.def("get_parameter_names", &migraphx::program::get_parameter_names)
|
||||
.def("get_parameter_shapes", &migraphx::program::get_parameter_shapes)
|
||||
.def("get_output_shapes", &migraphx::program::get_output_shapes)
|
||||
.def("is_compiled", &migraphx::program::is_compiled)
|
||||
.def(
|
||||
"compile",
|
||||
[](migraphx::program& p,
|
||||
const migraphx::target& t,
|
||||
bool offload_copy,
|
||||
bool fast_math,
|
||||
bool exhaustive_tune) {
|
||||
migraphx::compile_options options;
|
||||
options.offload_copy = offload_copy;
|
||||
options.fast_math = fast_math;
|
||||
options.exhaustive_tune = exhaustive_tune;
|
||||
p.compile(t, options);
|
||||
},
|
||||
py::arg("t"),
|
||||
py::arg("offload_copy") = true,
|
||||
py::arg("fast_math") = true,
|
||||
py::arg("exhaustive_tune") = false)
|
||||
.def("get_main_module", [](const migraphx::program& p) { return p.get_main_module(); })
|
||||
.def(
|
||||
"create_module",
|
||||
[](migraphx::program& p, const std::string& name) { return p.create_module(name); },
|
||||
py::arg("name"))
|
||||
.def("run",
|
||||
[](migraphx::program& p, py::dict params) {
|
||||
migraphx::parameter_map pm;
|
||||
for(auto x : params)
|
||||
{
|
||||
std::string key = x.first.cast<std::string>();
|
||||
py::buffer b = x.second.cast<py::buffer>();
|
||||
py::buffer_info info = b.request();
|
||||
pm[key] = migraphx::argument(to_shape(info), info.ptr);
|
||||
}
|
||||
return p.eval(pm);
|
||||
})
|
||||
.def("run_async",
|
||||
[](migraphx::program& p,
|
||||
py::dict params,
|
||||
std::uintptr_t stream,
|
||||
std::string stream_name) {
|
||||
migraphx::parameter_map pm;
|
||||
for(auto x : params)
|
||||
{
|
||||
std::string key = x.first.cast<std::string>();
|
||||
py::buffer b = x.second.cast<py::buffer>();
|
||||
py::buffer_info info = b.request();
|
||||
pm[key] = migraphx::argument(to_shape(info), info.ptr);
|
||||
}
|
||||
migraphx::execution_environment exec_env{
|
||||
migraphx::any_ptr(reinterpret_cast<void*>(stream), stream_name), true};
|
||||
return p.eval(pm, exec_env);
|
||||
})
|
||||
.def("sort", &migraphx::program::sort)
|
||||
.def("print", [](const migraphx::program& p) { std::cout << p << std::endl; })
|
||||
.def("__eq__", std::equal_to<migraphx::program>{})
|
||||
.def("__ne__", std::not_equal_to<migraphx::program>{})
|
||||
.def("__repr__", [](const migraphx::program& p) { return migraphx::to_string(p); });
|
||||
|
||||
py::class_<migraphx::operation> op(m, "op");
|
||||
op.def(py::init([](const std::string& name, py::kwargs kwargs) {
|
||||
migraphx::value v = migraphx::value::object{};
|
||||
if(kwargs)
|
||||
{
|
||||
v = migraphx::to_value(kwargs);
|
||||
}
|
||||
return migraphx::make_op(name, v);
|
||||
}))
|
||||
.def("name", &migraphx::operation::name);
|
||||
|
||||
py::enum_<migraphx::op::pooling_mode>(op, "pooling_mode")
|
||||
.value("average", migraphx::op::pooling_mode::average)
|
||||
.value("max", migraphx::op::pooling_mode::max)
|
||||
.value("lpnorm", migraphx::op::pooling_mode::lpnorm);
|
||||
|
||||
py::enum_<migraphx::op::rnn_direction>(op, "rnn_direction")
|
||||
.value("forward", migraphx::op::rnn_direction::forward)
|
||||
.value("reverse", migraphx::op::rnn_direction::reverse)
|
||||
.value("bidirectional", migraphx::op::rnn_direction::bidirectional);
|
||||
|
||||
m.def(
|
||||
"argument_from_pointer",
|
||||
[](const migraphx::shape shape, const int64_t address) {
|
||||
return migraphx::argument(shape, reinterpret_cast<void*>(address));
|
||||
},
|
||||
py::arg("shape"),
|
||||
py::arg("address"));
|
||||
|
||||
m.def(
|
||||
"parse_tf",
|
||||
[](const std::string& filename,
|
||||
bool is_nhwc,
|
||||
unsigned int batch_size,
|
||||
std::unordered_map<std::string, std::vector<std::size_t>> map_input_dims,
|
||||
std::vector<std::string> output_names) {
|
||||
return migraphx::parse_tf(
|
||||
filename, migraphx::tf_options{is_nhwc, batch_size, map_input_dims, output_names});
|
||||
},
|
||||
"Parse tf protobuf (default format is nhwc)",
|
||||
py::arg("filename"),
|
||||
py::arg("is_nhwc") = true,
|
||||
py::arg("batch_size") = 1,
|
||||
py::arg("map_input_dims") = std::unordered_map<std::string, std::vector<std::size_t>>(),
|
||||
py::arg("output_names") = std::vector<std::string>());
|
||||
|
||||
m.def(
|
||||
"parse_onnx",
|
||||
[](const std::string& filename,
|
||||
unsigned int default_dim_value,
|
||||
migraphx::shape::dynamic_dimension default_dyn_dim_value,
|
||||
std::unordered_map<std::string, std::vector<std::size_t>> map_input_dims,
|
||||
std::unordered_map<std::string, std::vector<migraphx::shape::dynamic_dimension>>
|
||||
map_dyn_input_dims,
|
||||
bool skip_unknown_operators,
|
||||
bool print_program_on_error,
|
||||
int64_t max_loop_iterations) {
|
||||
migraphx::onnx_options options;
|
||||
options.default_dim_value = default_dim_value;
|
||||
options.default_dyn_dim_value = default_dyn_dim_value;
|
||||
options.map_input_dims = map_input_dims;
|
||||
options.map_dyn_input_dims = map_dyn_input_dims;
|
||||
options.skip_unknown_operators = skip_unknown_operators;
|
||||
options.print_program_on_error = print_program_on_error;
|
||||
options.max_loop_iterations = max_loop_iterations;
|
||||
return migraphx::parse_onnx(filename, options);
|
||||
},
|
||||
"Parse onnx file",
|
||||
py::arg("filename"),
|
||||
py::arg("default_dim_value") = 0,
|
||||
py::arg("default_dyn_dim_value") = migraphx::shape::dynamic_dimension{1, 1},
|
||||
py::arg("map_input_dims") = std::unordered_map<std::string, std::vector<std::size_t>>(),
|
||||
py::arg("map_dyn_input_dims") =
|
||||
std::unordered_map<std::string, std::vector<migraphx::shape::dynamic_dimension>>(),
|
||||
py::arg("skip_unknown_operators") = false,
|
||||
py::arg("print_program_on_error") = false,
|
||||
py::arg("max_loop_iterations") = 10);
|
||||
|
||||
m.def(
|
||||
"parse_onnx_buffer",
|
||||
[](const std::string& onnx_buffer,
|
||||
unsigned int default_dim_value,
|
||||
migraphx::shape::dynamic_dimension default_dyn_dim_value,
|
||||
std::unordered_map<std::string, std::vector<std::size_t>> map_input_dims,
|
||||
std::unordered_map<std::string, std::vector<migraphx::shape::dynamic_dimension>>
|
||||
map_dyn_input_dims,
|
||||
bool skip_unknown_operators,
|
||||
bool print_program_on_error) {
|
||||
migraphx::onnx_options options;
|
||||
options.default_dim_value = default_dim_value;
|
||||
options.default_dyn_dim_value = default_dyn_dim_value;
|
||||
options.map_input_dims = map_input_dims;
|
||||
options.map_dyn_input_dims = map_dyn_input_dims;
|
||||
options.skip_unknown_operators = skip_unknown_operators;
|
||||
options.print_program_on_error = print_program_on_error;
|
||||
return migraphx::parse_onnx_buffer(onnx_buffer, options);
|
||||
},
|
||||
"Parse onnx file",
|
||||
py::arg("filename"),
|
||||
py::arg("default_dim_value") = 0,
|
||||
py::arg("default_dyn_dim_value") = migraphx::shape::dynamic_dimension{1, 1},
|
||||
py::arg("map_input_dims") = std::unordered_map<std::string, std::vector<std::size_t>>(),
|
||||
py::arg("map_dyn_input_dims") =
|
||||
std::unordered_map<std::string, std::vector<migraphx::shape::dynamic_dimension>>(),
|
||||
py::arg("skip_unknown_operators") = false,
|
||||
py::arg("print_program_on_error") = false);
|
||||
|
||||
m.def(
|
||||
"load",
|
||||
[](const std::string& name, const std::string& format) {
|
||||
migraphx::file_options options;
|
||||
options.format = format;
|
||||
return migraphx::load(name, options);
|
||||
},
|
||||
"Load MIGraphX program",
|
||||
py::arg("filename"),
|
||||
py::arg("format") = "msgpack");
|
||||
|
||||
m.def(
|
||||
"save",
|
||||
[](const migraphx::program& p, const std::string& name, const std::string& format) {
|
||||
migraphx::file_options options;
|
||||
options.format = format;
|
||||
return migraphx::save(p, name, options);
|
||||
},
|
||||
"Save MIGraphX program",
|
||||
py::arg("p"),
|
||||
py::arg("filename"),
|
||||
py::arg("format") = "msgpack");
|
||||
|
||||
m.def("get_target", &migraphx::make_target);
|
||||
m.def("create_argument", [](const migraphx::shape& s, const std::vector<double>& values) {
|
||||
if(values.size() != s.elements())
|
||||
MIGRAPHX_THROW("Values and shape elements do not match");
|
||||
migraphx::argument a{s};
|
||||
a.fill(values.begin(), values.end());
|
||||
return a;
|
||||
});
|
||||
m.def("generate_argument", &migraphx::generate_argument, py::arg("s"), py::arg("seed") = 0);
|
||||
m.def("fill_argument", &migraphx::fill_argument, py::arg("s"), py::arg("value"));
|
||||
m.def("quantize_fp16",
|
||||
&migraphx::quantize_fp16,
|
||||
py::arg("prog"),
|
||||
py::arg("ins_names") = std::vector<std::string>{"all"});
|
||||
m.def("quantize_int8",
|
||||
&migraphx::quantize_int8,
|
||||
py::arg("prog"),
|
||||
py::arg("t"),
|
||||
py::arg("calibration") = std::vector<migraphx::parameter_map>{},
|
||||
py::arg("ins_names") = std::vector<std::string>{"dot", "convolution"});
|
||||
|
||||
#ifdef HAVE_GPU
|
||||
m.def("allocate_gpu", &migraphx::gpu::allocate_gpu, py::arg("s"), py::arg("host") = false);
|
||||
m.def("to_gpu", &migraphx::gpu::to_gpu, py::arg("arg"), py::arg("host") = false);
|
||||
m.def("from_gpu", &migraphx::gpu::from_gpu);
|
||||
m.def("gpu_sync", [] { migraphx::gpu::gpu_sync(); });
|
||||
#endif
|
||||
|
||||
#ifdef VERSION_INFO
|
||||
m.attr("__version__") = VERSION_INFO;
|
||||
#else
|
||||
m.attr("__version__") = "dev";
|
||||
#endif
|
||||
}
|
1
docker/rocm/requirements-wheels-rocm.txt
Normal file
@@ -0,0 +1 @@
|
||||
onnxruntime-migraphx @ https://github.com/NickM-27/frigate-onnxruntime-rocm/releases/download/v7.0.1/onnxruntime_migraphx-1.23.0-cp311-cp311-linux_x86_64.whl
|
@@ -1,3 +0,0 @@
|
||||
Package: *
|
||||
Pin: release o=repo.radeon.com
|
||||
Pin-Priority: 600
|
@@ -2,7 +2,7 @@ variable "AMDGPU" {
|
||||
default = "gfx900"
|
||||
}
|
||||
variable "ROCM" {
|
||||
default = "5.7.3"
|
||||
default = "7.0.1"
|
||||
}
|
||||
variable "HSA_OVERRIDE_GFX_VERSION" {
|
||||
default = ""
|
||||
@@ -10,6 +10,13 @@ variable "HSA_OVERRIDE_GFX_VERSION" {
|
||||
variable "HSA_OVERRIDE" {
|
||||
default = "1"
|
||||
}
|
||||
|
||||
target wget {
|
||||
dockerfile = "docker/main/Dockerfile"
|
||||
platforms = ["linux/amd64"]
|
||||
target = "wget"
|
||||
}
|
||||
|
||||
target deps {
|
||||
dockerfile = "docker/main/Dockerfile"
|
||||
platforms = ["linux/amd64"]
|
||||
@@ -26,6 +33,7 @@ target rocm {
|
||||
dockerfile = "docker/rocm/Dockerfile"
|
||||
contexts = {
|
||||
deps = "target:deps",
|
||||
wget = "target:wget",
|
||||
rootfs = "target:rootfs"
|
||||
}
|
||||
platforms = ["linux/amd64"]
|
||||
|
@@ -1 +0,0 @@
|
||||
deb [arch=amd64 signed-by=/etc/apt/keyrings/rocm.gpg] https://repo.radeon.com/rocm/apt/5.7.3 focal main
|
@@ -4,14 +4,50 @@ BOARDS += rocm
|
||||
ROCM_CHIPSETS:=gfx900:9.0.0 gfx1030:10.3.0 gfx1100:11.0.0
|
||||
|
||||
local-rocm: version
|
||||
$(foreach chipset,$(ROCM_CHIPSETS),AMDGPU=$(word 1,$(subst :, ,$(chipset))) HSA_OVERRIDE_GFX_VERSION=$(word 2,$(subst :, ,$(chipset))) HSA_OVERRIDE=1 docker buildx bake --load --file=docker/rocm/rocm.hcl --set rocm.tags=frigate:latest-rocm-$(word 1,$(subst :, ,$(chipset))) rocm;)
|
||||
unset HSA_OVERRIDE_GFX_VERSION && HSA_OVERRIDE=0 AMDGPU=gfx docker buildx bake --load --file=docker/rocm/rocm.hcl --set rocm.tags=frigate:latest-rocm rocm
|
||||
$(foreach chipset,$(ROCM_CHIPSETS), \
|
||||
AMDGPU=$(word 1,$(subst :, ,$(chipset))) \
|
||||
HSA_OVERRIDE_GFX_VERSION=$(word 2,$(subst :, ,$(chipset))) \
|
||||
HSA_OVERRIDE=1 \
|
||||
docker buildx bake --file=docker/rocm/rocm.hcl rocm \
|
||||
--set rocm.tags=frigate:latest-rocm-$(word 1,$(subst :, ,$(chipset))) \
|
||||
--load \
|
||||
&&) true
|
||||
|
||||
unset HSA_OVERRIDE_GFX_VERSION && \
|
||||
HSA_OVERRIDE=0 \
|
||||
AMDGPU=gfx \
|
||||
docker buildx bake --file=docker/rocm/rocm.hcl rocm \
|
||||
--set rocm.tags=frigate:latest-rocm \
|
||||
--load
|
||||
|
||||
build-rocm: version
|
||||
$(foreach chipset,$(ROCM_CHIPSETS),AMDGPU=$(word 1,$(subst :, ,$(chipset))) HSA_OVERRIDE_GFX_VERSION=$(word 2,$(subst :, ,$(chipset))) HSA_OVERRIDE=1 docker buildx bake --file=docker/rocm/rocm.hcl --set rocm.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-rocm-$(chipset) rocm;)
|
||||
unset HSA_OVERRIDE_GFX_VERSION && HSA_OVERRIDE=0 AMDGPU=gfx docker buildx bake --file=docker/rocm/rocm.hcl --set rocm.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-rocm rocm
|
||||
$(foreach chipset,$(ROCM_CHIPSETS), \
|
||||
AMDGPU=$(word 1,$(subst :, ,$(chipset))) \
|
||||
HSA_OVERRIDE_GFX_VERSION=$(word 2,$(subst :, ,$(chipset))) \
|
||||
HSA_OVERRIDE=1 \
|
||||
docker buildx bake --file=docker/rocm/rocm.hcl rocm \
|
||||
--set rocm.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-rocm-$(chipset) \
|
||||
&&) true
|
||||
|
||||
unset HSA_OVERRIDE_GFX_VERSION && \
|
||||
HSA_OVERRIDE=0 \
|
||||
AMDGPU=gfx \
|
||||
docker buildx bake --file=docker/rocm/rocm.hcl rocm \
|
||||
--set rocm.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-rocm
|
||||
|
||||
push-rocm: build-rocm
|
||||
$(foreach chipset,$(ROCM_CHIPSETS),AMDGPU=$(word 1,$(subst :, ,$(chipset))) HSA_OVERRIDE_GFX_VERSION=$(word 2,$(subst :, ,$(chipset))) HSA_OVERRIDE=1 docker buildx bake --push --file=docker/rocm/rocm.hcl --set rocm.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-rocm-$(chipset) rocm;)
|
||||
unset HSA_OVERRIDE_GFX_VERSION && HSA_OVERRIDE=0 AMDGPU=gfx docker buildx bake --push --file=docker/rocm/rocm.hcl --set rocm.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-rocm rocm
|
||||
$(foreach chipset,$(ROCM_CHIPSETS), \
|
||||
AMDGPU=$(word 1,$(subst :, ,$(chipset))) \
|
||||
HSA_OVERRIDE_GFX_VERSION=$(word 2,$(subst :, ,$(chipset))) \
|
||||
HSA_OVERRIDE=1 \
|
||||
docker buildx bake --file=docker/rocm/rocm.hcl rocm \
|
||||
--set rocm.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-rocm-$(chipset) \
|
||||
--push \
|
||||
&&) true
|
||||
|
||||
unset HSA_OVERRIDE_GFX_VERSION && \
|
||||
HSA_OVERRIDE=0 \
|
||||
AMDGPU=gfx \
|
||||
docker buildx bake --file=docker/rocm/rocm.hcl rocm \
|
||||
--set rocm.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-rocm \
|
||||
--push
|
||||
|