Compare commits
No commits in common. "dev" and "v0.15.2" have entirely different histories.
@ -2,7 +2,6 @@ aarch
|
|||||||
absdiff
|
absdiff
|
||||||
airockchip
|
airockchip
|
||||||
Alloc
|
Alloc
|
||||||
alpr
|
|
||||||
Amcrest
|
Amcrest
|
||||||
amdgpu
|
amdgpu
|
||||||
analyzeduration
|
analyzeduration
|
||||||
@ -44,7 +43,6 @@ codeproject
|
|||||||
colormap
|
colormap
|
||||||
colorspace
|
colorspace
|
||||||
comms
|
comms
|
||||||
cooldown
|
|
||||||
coro
|
coro
|
||||||
ctypeslib
|
ctypeslib
|
||||||
CUDA
|
CUDA
|
||||||
@ -63,7 +61,6 @@ dsize
|
|||||||
dtype
|
dtype
|
||||||
ECONNRESET
|
ECONNRESET
|
||||||
edgetpu
|
edgetpu
|
||||||
facenet
|
|
||||||
fastapi
|
fastapi
|
||||||
faststart
|
faststart
|
||||||
fflags
|
fflags
|
||||||
@ -108,8 +105,8 @@ imagestream
|
|||||||
imdecode
|
imdecode
|
||||||
imencode
|
imencode
|
||||||
imread
|
imread
|
||||||
|
imutils
|
||||||
imwrite
|
imwrite
|
||||||
inpoint
|
|
||||||
interp
|
interp
|
||||||
iostat
|
iostat
|
||||||
iotop
|
iotop
|
||||||
@ -117,8 +114,6 @@ itemsize
|
|||||||
Jellyfin
|
Jellyfin
|
||||||
jetson
|
jetson
|
||||||
jetsons
|
jetsons
|
||||||
jina
|
|
||||||
jinaai
|
|
||||||
joserfc
|
joserfc
|
||||||
jsmpeg
|
jsmpeg
|
||||||
jsonify
|
jsonify
|
||||||
@ -191,9 +186,7 @@ ONVIF
|
|||||||
openai
|
openai
|
||||||
opencv
|
opencv
|
||||||
openvino
|
openvino
|
||||||
overfitting
|
|
||||||
OWASP
|
OWASP
|
||||||
paddleocr
|
|
||||||
paho
|
paho
|
||||||
passwordless
|
passwordless
|
||||||
popleft
|
popleft
|
||||||
@ -266,7 +259,6 @@ tensorrt
|
|||||||
tflite
|
tflite
|
||||||
thresholded
|
thresholded
|
||||||
timelapse
|
timelapse
|
||||||
titlecase
|
|
||||||
tmpfs
|
tmpfs
|
||||||
tobytes
|
tobytes
|
||||||
toggleable
|
toggleable
|
||||||
|
|||||||
@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
globs: ["**/*.ts", "**/*.tsx"]
|
|
||||||
alwaysApply: false
|
|
||||||
---
|
|
||||||
|
|
||||||
Never write strings in the frontend directly, always write to and reference the relevant translations file.
|
|
||||||
@ -8,25 +8,9 @@
|
|||||||
"overrideCommand": false,
|
"overrideCommand": false,
|
||||||
"remoteUser": "vscode",
|
"remoteUser": "vscode",
|
||||||
"features": {
|
"features": {
|
||||||
"ghcr.io/devcontainers/features/common-utils:2": {}
|
"ghcr.io/devcontainers/features/common-utils:1": {}
|
||||||
// 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": [
|
"forwardPorts": [8971, 5000, 5001, 5173, 8554, 8555],
|
||||||
8971,
|
|
||||||
5000,
|
|
||||||
5001,
|
|
||||||
5173,
|
|
||||||
8554,
|
|
||||||
8555
|
|
||||||
],
|
|
||||||
"portsAttributes": {
|
"portsAttributes": {
|
||||||
"8971": {
|
"8971": {
|
||||||
"label": "External NGINX",
|
"label": "External NGINX",
|
||||||
@ -80,18 +64,10 @@
|
|||||||
"editor.formatOnType": true,
|
"editor.formatOnType": true,
|
||||||
"python.testing.pytestEnabled": false,
|
"python.testing.pytestEnabled": false,
|
||||||
"python.testing.unittestEnabled": true,
|
"python.testing.unittestEnabled": true,
|
||||||
"python.testing.unittestArgs": [
|
"python.testing.unittestArgs": ["-v", "-s", "./frigate/test"],
|
||||||
"-v",
|
|
||||||
"-s",
|
|
||||||
"./frigate/test"
|
|
||||||
],
|
|
||||||
"files.trimTrailingWhitespace": true,
|
"files.trimTrailingWhitespace": true,
|
||||||
"eslint.workingDirectories": [
|
"eslint.workingDirectories": ["./web"],
|
||||||
"./web"
|
"isort.args": ["--settings-path=./pyproject.toml"],
|
||||||
],
|
|
||||||
"isort.args": [
|
|
||||||
"--settings-path=./pyproject.toml"
|
|
||||||
],
|
|
||||||
"[python]": {
|
"[python]": {
|
||||||
"editor.defaultFormatter": "charliermarsh.ruff",
|
"editor.defaultFormatter": "charliermarsh.ruff",
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
@ -110,15 +86,8 @@
|
|||||||
],
|
],
|
||||||
"editor.tabSize": 2
|
"editor.tabSize": 2
|
||||||
},
|
},
|
||||||
"cSpell.ignoreWords": [
|
"cSpell.ignoreWords": ["rtmp"],
|
||||||
"rtmp"
|
"cSpell.words": ["preact", "astype", "hwaccel", "mqtt"]
|
||||||
],
|
|
||||||
"cSpell.words": [
|
|
||||||
"preact",
|
|
||||||
"astype",
|
|
||||||
"hwaccel",
|
|
||||||
"mqtt"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"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"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
#!/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!"
|
|
||||||
@ -19,7 +19,7 @@ sudo chown -R "$(id -u):$(id -g)" /media/frigate
|
|||||||
# When started as a service, LIBAVFORMAT_VERSION_MAJOR is defined in the
|
# When started as a service, LIBAVFORMAT_VERSION_MAJOR is defined in the
|
||||||
# s6 service file. For dev, where frigate is started from an interactive
|
# s6 service file. For dev, where frigate is started from an interactive
|
||||||
# shell, we define it in .bashrc instead.
|
# shell, we define it in .bashrc instead.
|
||||||
echo 'export LIBAVFORMAT_VERSION_MAJOR=$("$(python3 /usr/local/ffmpeg/get_ffmpeg_path.py)" -version | grep -Po "libavformat\W+\K\d+")' >> "$HOME/.bashrc"
|
echo 'export LIBAVFORMAT_VERSION_MAJOR=$(/usr/lib/ffmpeg/7.0/bin/ffmpeg -version | grep -Po "libavformat\W+\K\d+")' >> $HOME/.bashrc
|
||||||
|
|
||||||
make version
|
make version
|
||||||
|
|
||||||
|
|||||||
@ -73,7 +73,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Operating system
|
label: Operating system
|
||||||
options:
|
options:
|
||||||
- Home Assistant OS
|
- HassOS
|
||||||
- Debian
|
- Debian
|
||||||
- Other Linux
|
- Other Linux
|
||||||
- Proxmox
|
- Proxmox
|
||||||
@ -87,7 +87,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Install method
|
label: Install method
|
||||||
options:
|
options:
|
||||||
- Home Assistant Add-on
|
- HassOS Addon
|
||||||
- Docker Compose
|
- Docker Compose
|
||||||
- Docker CLI
|
- Docker CLI
|
||||||
- Proxmox via Docker
|
- Proxmox via Docker
|
||||||
|
|||||||
@ -59,7 +59,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Operating system
|
label: Operating system
|
||||||
options:
|
options:
|
||||||
- Home Assistant OS
|
- HassOS
|
||||||
- Debian
|
- Debian
|
||||||
- Other Linux
|
- Other Linux
|
||||||
- Proxmox
|
- Proxmox
|
||||||
@ -73,7 +73,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Install method
|
label: Install method
|
||||||
options:
|
options:
|
||||||
- Home Assistant Add-on
|
- HassOS Addon
|
||||||
- Docker Compose
|
- Docker Compose
|
||||||
- Docker CLI
|
- Docker CLI
|
||||||
- Proxmox via Docker
|
- Proxmox via Docker
|
||||||
|
|||||||
@ -53,7 +53,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Install method
|
label: Install method
|
||||||
options:
|
options:
|
||||||
- Home Assistant Add-on
|
- HassOS Addon
|
||||||
- Docker Compose
|
- Docker Compose
|
||||||
- Docker CLI
|
- Docker CLI
|
||||||
- Proxmox via Docker
|
- Proxmox via Docker
|
||||||
|
|||||||
@ -73,7 +73,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Install method
|
label: Install method
|
||||||
options:
|
options:
|
||||||
- Home Assistant Add-on
|
- HassOS Addon
|
||||||
- Docker Compose
|
- Docker Compose
|
||||||
- Docker CLI
|
- Docker CLI
|
||||||
- Proxmox via Docker
|
- Proxmox via Docker
|
||||||
|
|||||||
@ -69,7 +69,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Install method
|
label: Install method
|
||||||
options:
|
options:
|
||||||
- Home Assistant Add-on
|
- HassOS Addon
|
||||||
- Docker Compose
|
- Docker Compose
|
||||||
- Docker CLI
|
- Docker CLI
|
||||||
- Proxmox via Docker
|
- Proxmox via Docker
|
||||||
|
|||||||
9
.github/DISCUSSION_TEMPLATE/report-a-bug.yml
vendored
@ -6,7 +6,7 @@ body:
|
|||||||
value: |
|
value: |
|
||||||
Use this form to submit a reproducible bug in Frigate or Frigate's UI.
|
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.
|
Before submitting your bug report, please [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.**
|
**If you are unsure if your issue is actually a bug or not, please submit a support request first.**
|
||||||
|
|
||||||
@ -14,7 +14,6 @@ body:
|
|||||||
[prs]: https://www.github.com/blakeblackshear/frigate/pulls
|
[prs]: https://www.github.com/blakeblackshear/frigate/pulls
|
||||||
[docs]: https://docs.frigate.video
|
[docs]: https://docs.frigate.video
|
||||||
[faq]: https://github.com/blakeblackshear/frigate/discussions/12724
|
[faq]: https://github.com/blakeblackshear/frigate/discussions/12724
|
||||||
[ai]: https://docs.frigate.video
|
|
||||||
- type: checkboxes
|
- type: checkboxes
|
||||||
attributes:
|
attributes:
|
||||||
label: Checklist
|
label: Checklist
|
||||||
@ -27,8 +26,6 @@ body:
|
|||||||
- label: I have tried a different browser to see if it is related to my browser.
|
- label: I have tried a different browser to see if it is related to my browser.
|
||||||
required: true
|
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 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
|
- type: textarea
|
||||||
id: description
|
id: description
|
||||||
attributes:
|
attributes:
|
||||||
@ -100,7 +97,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Operating system
|
label: Operating system
|
||||||
options:
|
options:
|
||||||
- Home Assistant OS
|
- HassOS
|
||||||
- Debian
|
- Debian
|
||||||
- Other Linux
|
- Other Linux
|
||||||
- Proxmox
|
- Proxmox
|
||||||
@ -114,7 +111,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Install method
|
label: Install method
|
||||||
options:
|
options:
|
||||||
- Home Assistant Add-on
|
- HassOS Addon
|
||||||
- Docker Compose
|
- Docker Compose
|
||||||
- Docker CLI
|
- Docker CLI
|
||||||
validations:
|
validations:
|
||||||
|
|||||||
7
.github/pull_request_template.md
vendored
@ -1,11 +1,5 @@
|
|||||||
## Proposed change
|
## 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.
|
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
|
Please describe in detail any considerations, breaking changes, etc. that are
|
||||||
made in this pull request.
|
made in this pull request.
|
||||||
@ -35,5 +29,4 @@
|
|||||||
- [ ] The code change is tested and works locally.
|
- [ ] The code change is tested and works locally.
|
||||||
- [ ] Local tests pass. **Your PR cannot be merged unless tests pass**
|
- [ ] Local tests pass. **Your PR cannot be merged unless tests pass**
|
||||||
- [ ] There is no commented out code in this PR.
|
- [ ] 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`)
|
- [ ] The code has been formatted using Ruff (`ruff format frigate`)
|
||||||
|
|||||||
116
.github/workflows/ci.yml
vendored
@ -15,7 +15,7 @@ concurrency:
|
|||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
env:
|
env:
|
||||||
PYTHON_VERSION: 3.11
|
PYTHON_VERSION: 3.9
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
amd64_build:
|
amd64_build:
|
||||||
@ -23,7 +23,7 @@ jobs:
|
|||||||
name: AMD64 Build
|
name: AMD64 Build
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Set up QEMU and Buildx
|
- name: Set up QEMU and Buildx
|
||||||
@ -41,13 +41,12 @@ jobs:
|
|||||||
target: frigate
|
target: frigate
|
||||||
tags: ${{ steps.setup.outputs.image-name }}-amd64
|
tags: ${{ steps.setup.outputs.image-name }}-amd64
|
||||||
cache-from: type=registry,ref=${{ steps.setup.outputs.cache-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:
|
arm64_build:
|
||||||
runs-on: ubuntu-22.04-arm
|
runs-on: ubuntu-22.04
|
||||||
name: ARM Build
|
name: ARM Build
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Set up QEMU and Buildx
|
- name: Set up QEMU and Buildx
|
||||||
@ -77,12 +76,12 @@ jobs:
|
|||||||
rpi.tags=${{ steps.setup.outputs.image-name }}-rpi
|
rpi.tags=${{ steps.setup.outputs.image-name }}-rpi
|
||||||
*.cache-from=type=registry,ref=${{ steps.setup.outputs.cache-name }}-arm64
|
*.cache-from=type=registry,ref=${{ steps.setup.outputs.cache-name }}-arm64
|
||||||
*.cache-to=type=registry,ref=${{ steps.setup.outputs.cache-name }}-arm64,mode=max
|
*.cache-to=type=registry,ref=${{ steps.setup.outputs.cache-name }}-arm64,mode=max
|
||||||
jetson_jp6_build:
|
jetson_jp4_build:
|
||||||
runs-on: ubuntu-22.04-arm
|
runs-on: ubuntu-22.04
|
||||||
name: Jetson Jetpack 6
|
name: Jetson Jetpack 4
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Set up QEMU and Buildx
|
- name: Set up QEMU and Buildx
|
||||||
@ -90,12 +89,12 @@ jobs:
|
|||||||
uses: ./.github/actions/setup
|
uses: ./.github/actions/setup
|
||||||
with:
|
with:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Build and push TensorRT (Jetson, Jetpack 6)
|
- name: Build and push TensorRT (Jetson, Jetpack 4)
|
||||||
env:
|
env:
|
||||||
ARCH: arm64
|
ARCH: arm64
|
||||||
BASE_IMAGE: nvcr.io/nvidia/tensorrt:23.12-py3-igpu
|
BASE_IMAGE: timongentzsch/l4t-ubuntu20-opencv:latest
|
||||||
SLIM_BASE: nvcr.io/nvidia/tensorrt:23.12-py3-igpu
|
SLIM_BASE: timongentzsch/l4t-ubuntu20-opencv:latest
|
||||||
TRT_BASE: nvcr.io/nvidia/tensorrt:23.12-py3-igpu
|
TRT_BASE: timongentzsch/l4t-ubuntu20-opencv:latest
|
||||||
uses: docker/bake-action@v6
|
uses: docker/bake-action@v6
|
||||||
with:
|
with:
|
||||||
source: .
|
source: .
|
||||||
@ -103,9 +102,38 @@ jobs:
|
|||||||
targets: tensorrt
|
targets: tensorrt
|
||||||
files: docker/tensorrt/trt.hcl
|
files: docker/tensorrt/trt.hcl
|
||||||
set: |
|
set: |
|
||||||
tensorrt.tags=${{ steps.setup.outputs.image-name }}-tensorrt-jp6
|
tensorrt.tags=${{ steps.setup.outputs.image-name }}-tensorrt-jp4
|
||||||
*.cache-from=type=registry,ref=${{ steps.setup.outputs.cache-name }}-jp6
|
*.cache-from=type=registry,ref=${{ steps.setup.outputs.cache-name }}-jp4
|
||||||
*.cache-to=type=registry,ref=${{ steps.setup.outputs.cache-name }}-jp6,mode=max
|
*.cache-to=type=registry,ref=${{ steps.setup.outputs.cache-name }}-jp4,mode=max
|
||||||
|
jetson_jp5_build:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
name: Jetson Jetpack 5
|
||||||
|
steps:
|
||||||
|
- name: Check out code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
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 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@v6
|
||||||
|
with:
|
||||||
|
source: .
|
||||||
|
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
|
||||||
amd64_extra_builds:
|
amd64_extra_builds:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
name: AMD64 Extra Build
|
name: AMD64 Extra Build
|
||||||
@ -113,7 +141,7 @@ jobs:
|
|||||||
- amd64_build
|
- amd64_build
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Set up QEMU and Buildx
|
- name: Set up QEMU and Buildx
|
||||||
@ -132,29 +160,16 @@ jobs:
|
|||||||
files: docker/tensorrt/trt.hcl
|
files: docker/tensorrt/trt.hcl
|
||||||
set: |
|
set: |
|
||||||
tensorrt.tags=${{ steps.setup.outputs.image-name }}-tensorrt
|
tensorrt.tags=${{ steps.setup.outputs.image-name }}-tensorrt
|
||||||
*.cache-from=type=registry,ref=${{ steps.setup.outputs.cache-name }}-tensorrt
|
*.cache-from=type=registry,ref=${{ steps.setup.outputs.cache-name }}-amd64
|
||||||
*.cache-to=type=registry,ref=${{ steps.setup.outputs.cache-name }}-tensorrt,mode=max
|
*.cache-to=type=registry,ref=${{ steps.setup.outputs.cache-name }}-amd64,mode=max
|
||||||
- name: AMD/ROCm general build
|
|
||||||
env:
|
|
||||||
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:
|
arm64_extra_builds:
|
||||||
runs-on: ubuntu-22.04-arm
|
runs-on: ubuntu-22.04
|
||||||
name: ARM Extra Build
|
name: ARM Extra Build
|
||||||
needs:
|
needs:
|
||||||
- arm64_build
|
- arm64_build
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Set up QEMU and Buildx
|
- name: Set up QEMU and Buildx
|
||||||
@ -172,14 +187,15 @@ jobs:
|
|||||||
set: |
|
set: |
|
||||||
rk.tags=${{ steps.setup.outputs.image-name }}-rk
|
rk.tags=${{ steps.setup.outputs.image-name }}-rk
|
||||||
*.cache-from=type=gha
|
*.cache-from=type=gha
|
||||||
synaptics_build:
|
combined_extra_builds:
|
||||||
runs-on: ubuntu-22.04-arm
|
runs-on: ubuntu-22.04
|
||||||
name: Synaptics Build
|
name: Combined Extra Builds
|
||||||
needs:
|
needs:
|
||||||
|
- amd64_build
|
||||||
- arm64_build
|
- arm64_build
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Set up QEMU and Buildx
|
- name: Set up QEMU and Buildx
|
||||||
@ -187,15 +203,29 @@ jobs:
|
|||||||
uses: ./.github/actions/setup
|
uses: ./.github/actions/setup
|
||||||
with:
|
with:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Build and push Synaptics build
|
- name: Build and push Hailo-8l build
|
||||||
uses: docker/bake-action@v6
|
uses: docker/bake-action@v6
|
||||||
with:
|
with:
|
||||||
source: .
|
source: .
|
||||||
push: true
|
push: true
|
||||||
targets: synaptics
|
targets: h8l
|
||||||
files: docker/synaptics/synaptics.hcl
|
files: docker/hailo8l/h8l.hcl
|
||||||
set: |
|
set: |
|
||||||
synaptics.tags=${{ steps.setup.outputs.image-name }}-synaptics
|
h8l.tags=${{ steps.setup.outputs.image-name }}-h8l
|
||||||
|
*.cache-from=type=registry,ref=${{ steps.setup.outputs.cache-name }}-h8l
|
||||||
|
*.cache-to=type=registry,ref=${{ steps.setup.outputs.cache-name }}-h8l,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-from=type=gha
|
*.cache-from=type=gha
|
||||||
# The majority of users running arm64 are rpi users, so the rpi
|
# The majority of users running arm64 are rpi users, so the rpi
|
||||||
# build should be the primary arm64 image
|
# build should be the primary arm64 image
|
||||||
@ -211,7 +241,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
string: ${{ github.repository }}
|
string: ${{ github.repository }}
|
||||||
- name: Log in to the Container registry
|
- name: Log in to the Container registry
|
||||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1
|
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
|
|||||||
73
.github/workflows/pull_request.yml
vendored
@ -4,19 +4,42 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
- ".github/*.yml"
|
|
||||||
- ".github/DISCUSSION_TEMPLATE/**"
|
|
||||||
- ".github/ISSUE_TEMPLATE/**"
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
DEFAULT_PYTHON: 3.11
|
DEFAULT_PYTHON: 3.9
|
||||||
|
|
||||||
jobs:
|
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
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
- 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:
|
web_lint:
|
||||||
name: Web - Lint
|
name: Web - Lint
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- uses: actions/setup-node@master
|
- uses: actions/setup-node@master
|
||||||
@ -32,7 +55,7 @@ jobs:
|
|||||||
name: Web - Test
|
name: Web - Test
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- uses: actions/setup-node@master
|
- uses: actions/setup-node@master
|
||||||
@ -40,9 +63,6 @@ jobs:
|
|||||||
node-version: 20.x
|
node-version: 20.x
|
||||||
- run: npm install
|
- run: npm install
|
||||||
working-directory: ./web
|
working-directory: ./web
|
||||||
- name: Build web
|
|
||||||
run: npm run build
|
|
||||||
working-directory: ./web
|
|
||||||
# - name: Test
|
# - name: Test
|
||||||
# run: npm run test
|
# run: npm run test
|
||||||
# working-directory: ./web
|
# working-directory: ./web
|
||||||
@ -52,11 +72,11 @@ jobs:
|
|||||||
name: Python Checks
|
name: Python Checks
|
||||||
steps:
|
steps:
|
||||||
- name: Check out the repository
|
- name: Check out the repository
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||||
uses: actions/setup-python@v5.4.0
|
uses: actions/setup-python@v5.3.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||||
- name: Install requirements
|
- name: Install requirements
|
||||||
@ -75,21 +95,24 @@ jobs:
|
|||||||
name: Python Tests
|
name: Python Tests
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- uses: actions/setup-node@master
|
- uses: actions/setup-node@master
|
||||||
with:
|
with:
|
||||||
node-version: 20.x
|
node-version: 16.x
|
||||||
- name: Install devcontainer cli
|
- run: npm install
|
||||||
run: npm install --global @devcontainers/cli
|
working-directory: ./web
|
||||||
- name: Build devcontainer
|
- name: Build web
|
||||||
env:
|
run: npm run build
|
||||||
DOCKER_BUILDKIT: "1"
|
working-directory: ./web
|
||||||
run: devcontainer build --workspace-folder .
|
- name: Set up QEMU
|
||||||
- name: Start devcontainer
|
uses: docker/setup-qemu-action@v3
|
||||||
run: devcontainer up --workspace-folder .
|
- name: Set up Docker Buildx
|
||||||
- name: Run mypy in devcontainer
|
uses: docker/setup-buildx-action@v3
|
||||||
run: devcontainer exec --workspace-folder . bash -lc "python3 -u -m mypy --config-file frigate/mypy.ini frigate"
|
- name: Build
|
||||||
- name: Run unit tests in devcontainer
|
run: make
|
||||||
run: devcontainer exec --workspace-folder . bash -lc "python3 -u -m unittest"
|
- 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
|
||||||
|
|||||||
8
.github/workflows/release.yml
vendored
@ -10,7 +10,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- id: lowercaseRepo
|
- id: lowercaseRepo
|
||||||
@ -18,7 +18,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
string: ${{ github.repository }}
|
string: ${{ github.repository }}
|
||||||
- name: Log in to the Container registry
|
- name: Log in to the Container registry
|
||||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1
|
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
@ -39,14 +39,14 @@ jobs:
|
|||||||
STABLE_TAG=${BASE}:stable
|
STABLE_TAG=${BASE}:stable
|
||||||
PULL_TAG=${BASE}:${BUILD_TAG}
|
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}
|
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-jp6 rk rocm; do
|
for variant in standard-arm64 tensorrt tensorrt-jp4 tensorrt-jp5 rk h8l 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}
|
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
|
done
|
||||||
|
|
||||||
# stable tag
|
# stable tag
|
||||||
if [[ "${BUILD_TYPE}" == "stable" ]]; 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}
|
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-jp6 rk rocm; do
|
for variant in standard-arm64 tensorrt tensorrt-jp4 tensorrt-jp5 rk h8l 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}
|
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
|
done
|
||||||
fi
|
fi
|
||||||
|
|||||||
1
.gitignore
vendored
@ -15,7 +15,6 @@ frigate/version.py
|
|||||||
web/build
|
web/build
|
||||||
web/node_modules
|
web/node_modules
|
||||||
web/coverage
|
web/coverage
|
||||||
web/.env
|
|
||||||
core
|
core
|
||||||
!/web/**/*.ts
|
!/web/**/*.ts
|
||||||
.idea/*
|
.idea/*
|
||||||
|
|||||||
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
The MIT License
|
The MIT License
|
||||||
|
|
||||||
Copyright (c) 2025 Frigate LLC (Frigate™)
|
Copyright (c) 2020 Blake Blackshear
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
9
Makefile
@ -1,7 +1,7 @@
|
|||||||
default_target: local
|
default_target: local
|
||||||
|
|
||||||
COMMIT_HASH := $(shell git log -1 --pretty=format:"%h"|tail -1)
|
COMMIT_HASH := $(shell git log -1 --pretty=format:"%h"|tail -1)
|
||||||
VERSION = 0.17.0
|
VERSION = 0.15.2
|
||||||
IMAGE_REPO ?= ghcr.io/blakeblackshear/frigate
|
IMAGE_REPO ?= ghcr.io/blakeblackshear/frigate
|
||||||
GITHUB_REF_NAME ?= $(shell git rev-parse --abbrev-ref HEAD)
|
GITHUB_REF_NAME ?= $(shell git rev-parse --abbrev-ref HEAD)
|
||||||
BOARDS= #Initialized empty
|
BOARDS= #Initialized empty
|
||||||
@ -14,19 +14,12 @@ push-boards: $(BOARDS:%=push-%)
|
|||||||
|
|
||||||
version:
|
version:
|
||||||
echo 'VERSION = "$(VERSION)-$(COMMIT_HASH)"' > frigate/version.py
|
echo 'VERSION = "$(VERSION)-$(COMMIT_HASH)"' > frigate/version.py
|
||||||
echo 'VITE_GIT_COMMIT_HASH=$(COMMIT_HASH)' > web/.env
|
|
||||||
|
|
||||||
local: version
|
local: version
|
||||||
docker buildx build --target=frigate --file docker/main/Dockerfile . \
|
docker buildx build --target=frigate --file docker/main/Dockerfile . \
|
||||||
--tag frigate:latest \
|
--tag frigate:latest \
|
||||||
--load
|
--load
|
||||||
|
|
||||||
debug: version
|
|
||||||
docker buildx build --target=frigate --file docker/main/Dockerfile . \
|
|
||||||
--build-arg DEBUG=true \
|
|
||||||
--tag frigate:latest \
|
|
||||||
--load
|
|
||||||
|
|
||||||
amd64:
|
amd64:
|
||||||
docker buildx build --target=frigate --file docker/main/Dockerfile . \
|
docker buildx build --target=frigate --file docker/main/Dockerfile . \
|
||||||
--tag $(IMAGE_REPO):$(VERSION)-$(COMMIT_HASH) \
|
--tag $(IMAGE_REPO):$(VERSION)-$(COMMIT_HASH) \
|
||||||
|
|||||||
39
README.md
@ -1,20 +1,12 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<img align="center" alt="logo" src="docs/static/img/branding/frigate.png">
|
<img align="center" alt="logo" src="docs/static/img/frigate.png">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
# Frigate NVR™ - Realtime Object Detection for IP Cameras
|
# Frigate - NVR With Realtime Object Detection for IP Cameras
|
||||||
|
|
||||||
[](https://opensource.org/licenses/MIT)
|
|
||||||
|
|
||||||
<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.
|
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 GPU or AI accelerator is highly recommended. AI accelerators will outperform even the best CPUs with very little overhead. See Frigate's supported [object detectors](https://docs.frigate.video/configuration/object_detectors/).
|
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.
|
||||||
|
|
||||||
- Tight integration with Home Assistant via a [custom component](https://github.com/blakeblackshear/frigate-hass-integration)
|
- 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
|
- Designed to minimize resource use and maximize performance by only looking for objects when and where it is necessary
|
||||||
@ -35,49 +27,24 @@ View the documentation at https://docs.frigate.video
|
|||||||
|
|
||||||
If you would like to make a donation to support development, please use [Github Sponsors](https://github.com/sponsors/blakeblackshear).
|
If you would like to make a donation to support development, please use [Github Sponsors](https://github.com/sponsors/blakeblackshear).
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
This project is licensed under the **MIT License**.
|
|
||||||
|
|
||||||
- **Code:** The source code, configuration files, and documentation in this repository are available under the [MIT License](LICENSE). You are free to use, modify, and distribute the code as long as you include the original copyright notice.
|
|
||||||
- **Trademarks:** The "Frigate" name, the "Frigate NVR" brand, and the Frigate logo are **trademarks of Frigate LLC** and are **not** covered by the MIT License.
|
|
||||||
|
|
||||||
Please see our [Trademark Policy](TRADEMARK.md) for details on acceptable use of our brand assets.
|
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
### Live dashboard
|
### Live dashboard
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<img width="800" alt="Live dashboard" src="https://github.com/blakeblackshear/frigate/assets/569905/5e713cb9-9db5-41dc-947a-6937c3bc376e">
|
<img width="800" alt="Live dashboard" src="https://github.com/blakeblackshear/frigate/assets/569905/5e713cb9-9db5-41dc-947a-6937c3bc376e">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
### Streamlined review workflow
|
### Streamlined review workflow
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<img width="800" alt="Streamlined review workflow" src="https://github.com/blakeblackshear/frigate/assets/569905/6fed96e8-3b18-40e5-9ddc-31e6f3c9f2ff">
|
<img width="800" alt="Streamlined review workflow" src="https://github.com/blakeblackshear/frigate/assets/569905/6fed96e8-3b18-40e5-9ddc-31e6f3c9f2ff">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
### Multi-camera scrubbing
|
### Multi-camera scrubbing
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<img width="800" alt="Multi-camera scrubbing" src="https://github.com/blakeblackshear/frigate/assets/569905/d6788a15-0eeb-4427-a8d4-80b93cae3d74">
|
<img width="800" alt="Multi-camera scrubbing" src="https://github.com/blakeblackshear/frigate/assets/569905/d6788a15-0eeb-4427-a8d4-80b93cae3d74">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
### Built-in mask and zone editor
|
### Built-in mask and zone editor
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<img width="800" alt="Multi-camera scrubbing" src="https://github.com/blakeblackshear/frigate/assets/569905/d7885fc3-bfe6-452f-b7d0-d957cb3e31f5">
|
<img width="800" alt="Multi-camera scrubbing" src="https://github.com/blakeblackshear/frigate/assets/569905/d7885fc3-bfe6-452f-b7d0-d957cb3e31f5">
|
||||||
</div>
|
</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>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Copyright © 2025 Frigate LLC.**
|
|
||||||
|
|||||||
89
README_CN.md
@ -1,89 +0,0 @@
|
|||||||
<p align="center">
|
|
||||||
<img align="center" alt="logo" src="docs/static/img/branding/frigate.png">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
# Frigate NVR™ - 一个具有实时目标检测的本地 NVR
|
|
||||||
|
|
||||||
[English](https://github.com/blakeblackshear/frigate) | \[简体中文\]
|
|
||||||
|
|
||||||
[](https://opensource.org/licenses/MIT)
|
|
||||||
|
|
||||||
<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)。
|
|
||||||
|
|
||||||
## 协议
|
|
||||||
|
|
||||||
本项目采用 **MIT 许可证**授权。
|
|
||||||
**代码部分**:本代码库中的源代码、配置文件和文档均遵循 [MIT 许可证](LICENSE)。您可以自由使用、修改和分发这些代码,但必须保留原始版权声明。
|
|
||||||
|
|
||||||
**商标部分**:“Frigate”名称、“Frigate NVR”品牌以及 Frigate 的 Logo 为 **Frigate LLC 的商标**,**不在** MIT 许可证覆盖范围内。
|
|
||||||
有关品牌资产的规范使用详情,请参阅我们的[《商标政策》](TRADEMARK.md)。
|
|
||||||
|
|
||||||
## 截图
|
|
||||||
|
|
||||||
### 实时监控面板
|
|
||||||
|
|
||||||
<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 赞助
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Copyright © 2025 Frigate LLC.**
|
|
||||||
58
TRADEMARK.md
@ -1,58 +0,0 @@
|
|||||||
# Trademark Policy
|
|
||||||
|
|
||||||
**Last Updated:** November 2025
|
|
||||||
|
|
||||||
This document outlines the policy regarding the use of the trademarks associated with the Frigate NVR project.
|
|
||||||
|
|
||||||
## 1. Our Trademarks
|
|
||||||
|
|
||||||
The following terms and visual assets are trademarks (the "Marks") of **Frigate LLC**:
|
|
||||||
|
|
||||||
- **Frigate™**
|
|
||||||
- **Frigate NVR™**
|
|
||||||
- **Frigate+™**
|
|
||||||
- **The Frigate Logo**
|
|
||||||
|
|
||||||
**Note on Common Law Rights:**
|
|
||||||
Frigate LLC asserts all common law rights in these Marks. The absence of a federal registration symbol (®) does not constitute a waiver of our intellectual property rights.
|
|
||||||
|
|
||||||
## 2. Interaction with the MIT License
|
|
||||||
|
|
||||||
The software in this repository is licensed under the [MIT License](LICENSE).
|
|
||||||
|
|
||||||
**Crucial Distinction:**
|
|
||||||
|
|
||||||
- The **Code** is free to use, modify, and distribute under the MIT terms.
|
|
||||||
- The **Brand (Trademarks)** is **NOT** licensed under MIT.
|
|
||||||
|
|
||||||
You may not use the Marks in any way that is not explicitly permitted by this policy or by written agreement with Frigate LLC.
|
|
||||||
|
|
||||||
## 3. Acceptable Use
|
|
||||||
|
|
||||||
You may use the Marks without prior written permission in the following specific contexts:
|
|
||||||
|
|
||||||
- **Referential Use:** To truthfully refer to the software (e.g., _"I use Frigate NVR for my home security"_).
|
|
||||||
- **Compatibility:** To indicate that your product or project works with the software (e.g., _"MyPlugin for Frigate NVR"_ or _"Compatible with Frigate"_).
|
|
||||||
- **Commentary:** In news articles, blog posts, or tutorials discussing the software.
|
|
||||||
|
|
||||||
## 4. Prohibited Use
|
|
||||||
|
|
||||||
You may **NOT** use the Marks in the following ways:
|
|
||||||
|
|
||||||
- **Commercial Products:** You may not use "Frigate" in the name of a commercial product, service, or app (e.g., selling an app named _"Frigate Viewer"_ is prohibited).
|
|
||||||
- **Implying Affiliation:** You may not use the Marks in a way that suggests your project is official, sponsored by, or endorsed by Frigate LLC.
|
|
||||||
- **Confusing Forks:** If you fork this repository to create a derivative work, you **must** remove the Frigate logo and rename your project to avoid user confusion. You cannot distribute a modified version of the software under the name "Frigate".
|
|
||||||
- **Domain Names:** You may not register domain names containing "Frigate" that are likely to confuse users (e.g., `frigate-official-support.com`).
|
|
||||||
|
|
||||||
## 5. The Logo
|
|
||||||
|
|
||||||
The Frigate logo (the bird icon) is a visual trademark.
|
|
||||||
|
|
||||||
- You generally **cannot** use the logo on your own website or product packaging without permission.
|
|
||||||
- If you are building a dashboard or integration that interfaces with Frigate, you may use the logo only to represent the Frigate node/service, provided it does not imply you _are_ Frigate.
|
|
||||||
|
|
||||||
## 6. Questions & Permissions
|
|
||||||
|
|
||||||
If you are unsure if your intended use violates this policy, or if you wish to request a specific license to use the Marks (e.g., for a partnership), please contact us at:
|
|
||||||
|
|
||||||
**help@frigate.video**
|
|
||||||
@ -4,13 +4,13 @@ from statistics import mean
|
|||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
import frigate.util as util
|
||||||
from frigate.config import DetectorTypeEnum
|
from frigate.config import DetectorTypeEnum
|
||||||
from frigate.object_detection.base import (
|
from frigate.object_detection import (
|
||||||
ObjectDetectProcess,
|
ObjectDetectProcess,
|
||||||
RemoteObjectDetector,
|
RemoteObjectDetector,
|
||||||
load_labels,
|
load_labels,
|
||||||
)
|
)
|
||||||
from frigate.util.process import FrigateProcess
|
|
||||||
|
|
||||||
my_frame = np.expand_dims(np.full((300, 300, 3), 1, np.uint8), axis=0)
|
my_frame = np.expand_dims(np.full((300, 300, 3), 1, np.uint8), axis=0)
|
||||||
labels = load_labels("/labelmap.txt")
|
labels = load_labels("/labelmap.txt")
|
||||||
@ -91,7 +91,7 @@ edgetpu_process_2 = ObjectDetectProcess(
|
|||||||
)
|
)
|
||||||
|
|
||||||
for x in range(0, 10):
|
for x in range(0, 10):
|
||||||
camera_process = FrigateProcess(
|
camera_process = util.Process(
|
||||||
target=start, args=(x, 300, detection_queue, events[str(x)])
|
target=start, args=(x, 300, detection_queue, events[str(x)])
|
||||||
)
|
)
|
||||||
camera_process.daemon = True
|
camera_process.daemon = True
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
|
version: "3"
|
||||||
services:
|
services:
|
||||||
devcontainer:
|
devcontainer:
|
||||||
container_name: frigate-devcontainer
|
container_name: frigate-devcontainer
|
||||||
# Check host system's actual render/video/plugdev group IDs with 'getent group render', 'getent group video', and 'getent group plugdev'
|
# add groups from host for render, plugdev, video
|
||||||
# Must add these exact IDs in container's group_add section or OpenVINO GPU acceleration will fail
|
|
||||||
group_add:
|
group_add:
|
||||||
- "109" # render
|
- "109" # render
|
||||||
- "110" # render
|
- "110" # render
|
||||||
@ -24,8 +24,8 @@ services:
|
|||||||
# capabilities: [gpu]
|
# capabilities: [gpu]
|
||||||
environment:
|
environment:
|
||||||
YOLO_MODELS: ""
|
YOLO_MODELS: ""
|
||||||
# devices:
|
devices:
|
||||||
# - /dev/bus/usb:/dev/bus/usb # Uncomment for Google Coral USB
|
- /dev/bus/usb:/dev/bus/usb
|
||||||
# - /dev/dri:/dev/dri # for intel hwaccel, needs to be updated for your hardware
|
# - /dev/dri:/dev/dri # for intel hwaccel, needs to be updated for your hardware
|
||||||
volumes:
|
volumes:
|
||||||
- .:/workspace/frigate:cached
|
- .:/workspace/frigate:cached
|
||||||
@ -33,10 +33,9 @@ services:
|
|||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
- ./config:/config
|
- ./config:/config
|
||||||
- ./debug:/media/frigate
|
- ./debug:/media/frigate
|
||||||
# - /dev/bus/usb:/dev/bus/usb # Uncomment for Google Coral USB
|
- /dev/bus/usb:/dev/bus/usb
|
||||||
mqtt:
|
mqtt:
|
||||||
container_name: mqtt
|
container_name: mqtt
|
||||||
image: eclipse-mosquitto:2.0
|
image: eclipse-mosquitto:1.6
|
||||||
command: mosquitto -c /mosquitto-no-auth.conf # enable no-auth mode
|
|
||||||
ports:
|
ports:
|
||||||
- "1883:1883"
|
- "1883:1883"
|
||||||
|
|||||||
40
docker/hailo8l/Dockerfile
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# syntax=docker/dockerfile:1.6
|
||||||
|
|
||||||
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
# Build Python wheels
|
||||||
|
FROM wheels AS h8l-wheels
|
||||||
|
|
||||||
|
COPY docker/main/requirements-wheels.txt /requirements-wheels.txt
|
||||||
|
COPY docker/hailo8l/requirements-wheels-h8l.txt /requirements-wheels-h8l.txt
|
||||||
|
|
||||||
|
RUN sed -i "/https:\/\//d" /requirements-wheels.txt
|
||||||
|
|
||||||
|
# Create a directory to store the built wheels
|
||||||
|
RUN mkdir /h8l-wheels
|
||||||
|
|
||||||
|
# Build the wheels
|
||||||
|
RUN pip3 wheel --wheel-dir=/h8l-wheels -c /requirements-wheels.txt -r /requirements-wheels-h8l.txt
|
||||||
|
|
||||||
|
FROM wget AS hailort
|
||||||
|
ARG TARGETARCH
|
||||||
|
RUN --mount=type=bind,source=docker/hailo8l/install_hailort.sh,target=/deps/install_hailort.sh \
|
||||||
|
/deps/install_hailort.sh
|
||||||
|
|
||||||
|
# Use deps as the base image
|
||||||
|
FROM deps AS h8l-frigate
|
||||||
|
|
||||||
|
# Copy the wheels from the wheels stage
|
||||||
|
COPY --from=h8l-wheels /h8l-wheels /deps/h8l-wheels
|
||||||
|
COPY --from=hailort /hailo-wheels /deps/hailo-wheels
|
||||||
|
COPY --from=hailort /rootfs/ /
|
||||||
|
|
||||||
|
# Install the wheels
|
||||||
|
RUN pip3 install -U /deps/h8l-wheels/*.whl
|
||||||
|
RUN pip3 install -U /deps/hailo-wheels/*.whl
|
||||||
|
|
||||||
|
# Copy base files from the rootfs stage
|
||||||
|
COPY --from=rootfs / /
|
||||||
|
|
||||||
|
# Set workdir
|
||||||
|
WORKDIR /opt/frigate/
|
||||||
34
docker/hailo8l/h8l.hcl
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
target wget {
|
||||||
|
dockerfile = "docker/main/Dockerfile"
|
||||||
|
platforms = ["linux/arm64","linux/amd64"]
|
||||||
|
target = "wget"
|
||||||
|
}
|
||||||
|
|
||||||
|
target wheels {
|
||||||
|
dockerfile = "docker/main/Dockerfile"
|
||||||
|
platforms = ["linux/arm64","linux/amd64"]
|
||||||
|
target = "wheels"
|
||||||
|
}
|
||||||
|
|
||||||
|
target deps {
|
||||||
|
dockerfile = "docker/main/Dockerfile"
|
||||||
|
platforms = ["linux/arm64","linux/amd64"]
|
||||||
|
target = "deps"
|
||||||
|
}
|
||||||
|
|
||||||
|
target rootfs {
|
||||||
|
dockerfile = "docker/main/Dockerfile"
|
||||||
|
platforms = ["linux/arm64","linux/amd64"]
|
||||||
|
target = "rootfs"
|
||||||
|
}
|
||||||
|
|
||||||
|
target h8l {
|
||||||
|
dockerfile = "docker/hailo8l/Dockerfile"
|
||||||
|
contexts = {
|
||||||
|
wget = "target:wget"
|
||||||
|
wheels = "target:wheels"
|
||||||
|
deps = "target:deps"
|
||||||
|
rootfs = "target:rootfs"
|
||||||
|
}
|
||||||
|
platforms = ["linux/arm64","linux/amd64"]
|
||||||
|
}
|
||||||
15
docker/hailo8l/h8l.mk
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
BOARDS += h8l
|
||||||
|
|
||||||
|
local-h8l: version
|
||||||
|
docker buildx bake --file=docker/hailo8l/h8l.hcl h8l \
|
||||||
|
--set h8l.tags=frigate:latest-h8l \
|
||||||
|
--load
|
||||||
|
|
||||||
|
build-h8l: version
|
||||||
|
docker buildx bake --file=docker/hailo8l/h8l.hcl h8l \
|
||||||
|
--set h8l.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-h8l
|
||||||
|
|
||||||
|
push-h8l: build-h8l
|
||||||
|
docker buildx bake --file=docker/hailo8l/h8l.hcl h8l \
|
||||||
|
--set h8l.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-h8l \
|
||||||
|
--push
|
||||||
19
docker/hailo8l/install_hailort.sh
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
hailo_version="4.19.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-${TARGETARCH}.tar.gz" |
|
||||||
|
tar -C / -xzf -
|
||||||
|
|
||||||
|
mkdir -p /hailo-wheels
|
||||||
|
|
||||||
|
wget -P /hailo-wheels/ "https://github.com/frigate-nvr/hailort/releases/download/v${hailo_version}/hailort-${hailo_version}-cp39-cp39-linux_${arch}.whl"
|
||||||
|
|
||||||
12
docker/hailo8l/requirements-wheels-h8l.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
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.*
|
||||||
@ -4,7 +4,6 @@
|
|||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y build-essential cmake git wget
|
sudo apt-get install -y build-essential cmake git wget
|
||||||
|
|
||||||
hailo_version="4.21.0"
|
|
||||||
arch=$(uname -m)
|
arch=$(uname -m)
|
||||||
|
|
||||||
if [[ $arch == "x86_64" ]]; then
|
if [[ $arch == "x86_64" ]]; then
|
||||||
@ -14,7 +13,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Clone the HailoRT driver repository
|
# Clone the HailoRT driver repository
|
||||||
git clone --depth 1 --branch v${hailo_version} https://github.com/hailo-ai/hailort-drivers.git
|
git clone --depth 1 --branch v4.19.0 https://github.com/hailo-ai/hailort-drivers.git
|
||||||
|
|
||||||
# Build and install the HailoRT driver
|
# Build and install the HailoRT driver
|
||||||
cd hailort-drivers/linux/pcie
|
cd hailort-drivers/linux/pcie
|
||||||
|
|||||||
@ -3,29 +3,14 @@
|
|||||||
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
# Globally set pip break-system-packages option to avoid having to specify it every time
|
ARG BASE_IMAGE=debian:11
|
||||||
ARG PIP_BREAK_SYSTEM_PACKAGES=1
|
ARG SLIM_BASE=debian:11-slim
|
||||||
|
|
||||||
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
|
FROM ${BASE_IMAGE} AS base
|
||||||
ARG PIP_BREAK_SYSTEM_PACKAGES
|
|
||||||
ARG BASE_HOOK
|
|
||||||
|
|
||||||
RUN sh -c "$BASE_HOOK"
|
FROM --platform=${BUILDPLATFORM} debian:11 AS base_host
|
||||||
|
|
||||||
FROM --platform=${BUILDPLATFORM} debian:12 AS base_host
|
|
||||||
ARG PIP_BREAK_SYSTEM_PACKAGES
|
|
||||||
|
|
||||||
FROM ${SLIM_BASE} AS slim-base
|
FROM ${SLIM_BASE} AS slim-base
|
||||||
ARG PIP_BREAK_SYSTEM_PACKAGES
|
|
||||||
ARG BASE_HOOK
|
|
||||||
|
|
||||||
RUN sh -c "$BASE_HOOK"
|
|
||||||
|
|
||||||
FROM slim-base AS wget
|
FROM slim-base AS wget
|
||||||
ARG DEBIAN_FRONTEND
|
ARG DEBIAN_FRONTEND
|
||||||
@ -39,7 +24,10 @@ ARG DEBIAN_FRONTEND
|
|||||||
ENV CCACHE_DIR /root/.ccache
|
ENV CCACHE_DIR /root/.ccache
|
||||||
ENV CCACHE_MAXSIZE 2G
|
ENV CCACHE_MAXSIZE 2G
|
||||||
|
|
||||||
RUN --mount=type=bind,source=docker/main/build_nginx.sh,target=/deps/build_nginx.sh \
|
# 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 \
|
||||||
/deps/build_nginx.sh
|
/deps/build_nginx.sh
|
||||||
|
|
||||||
FROM wget AS sqlite-vec
|
FROM wget AS sqlite-vec
|
||||||
@ -55,7 +43,7 @@ RUN --mount=type=tmpfs,target=/tmp --mount=type=tmpfs,target=/var/cache/apt \
|
|||||||
FROM scratch AS go2rtc
|
FROM scratch AS go2rtc
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
WORKDIR /rootfs/usr/local/go2rtc/bin
|
WORKDIR /rootfs/usr/local/go2rtc/bin
|
||||||
ADD --link --chmod=755 "https://github.com/AlexxIT/go2rtc/releases/download/v1.9.10/go2rtc_linux_${TARGETARCH}" go2rtc
|
ADD --link --chmod=755 "https://github.com/AlexxIT/go2rtc/releases/download/v1.9.2/go2rtc_linux_${TARGETARCH}" go2rtc
|
||||||
|
|
||||||
FROM wget AS tempio
|
FROM wget AS tempio
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
@ -78,9 +66,8 @@ COPY docker/main/requirements-ov.txt /requirements-ov.txt
|
|||||||
RUN apt-get -qq update \
|
RUN apt-get -qq update \
|
||||||
&& apt-get -qq install -y wget python3 python3-dev python3-distutils gcc pkg-config libhdf5-dev \
|
&& 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 \
|
&& 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" \
|
&& python3 get-pip.py "pip" \
|
||||||
&& pip3 install -r /requirements-ov.txt
|
&& pip install -r /requirements-ov.txt
|
||||||
|
|
||||||
# Get OpenVino Model
|
# Get OpenVino Model
|
||||||
RUN --mount=type=bind,source=docker/main/build_ov_model.py,target=/build_ov_model.py \
|
RUN --mount=type=bind,source=docker/main/build_ov_model.py,target=/build_ov_model.py \
|
||||||
@ -148,22 +135,28 @@ RUN --mount=type=bind,source=docker/main/install_s6_overlay.sh,target=/deps/inst
|
|||||||
FROM base AS wheels
|
FROM base AS wheels
|
||||||
ARG DEBIAN_FRONTEND
|
ARG DEBIAN_FRONTEND
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
ARG DEBUG=false
|
|
||||||
|
|
||||||
# Use a separate container to build wheels to prevent build dependencies in final image
|
# Use a separate container to build wheels to prevent build dependencies in final image
|
||||||
RUN apt-get -qq update \
|
RUN apt-get -qq update \
|
||||||
&& apt-get -qq install -y \
|
&& apt-get -qq install -y \
|
||||||
apt-transport-https wget unzip \
|
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-get -qq update \
|
&& apt-get -qq update \
|
||||||
&& apt-get -qq install -y \
|
&& apt-get -qq install -y \
|
||||||
python3.11 \
|
python3.9 \
|
||||||
python3.11-dev \
|
python3.9-dev \
|
||||||
# opencv dependencies
|
# opencv dependencies
|
||||||
build-essential cmake git pkg-config libgtk-3-dev \
|
build-essential cmake git pkg-config libgtk-3-dev \
|
||||||
libavcodec-dev libavformat-dev libswscale-dev libv4l-dev \
|
libavcodec-dev libavformat-dev libswscale-dev libv4l-dev \
|
||||||
libxvidcore-dev libx264-dev libjpeg-dev libpng-dev libtiff-dev \
|
libxvidcore-dev libx264-dev libjpeg-dev libpng-dev libtiff-dev \
|
||||||
gfortran openexr libatlas-base-dev libssl-dev\
|
gfortran openexr libatlas-base-dev libssl-dev\
|
||||||
libtbbmalloc2 libtbb-dev libdc1394-dev libopenexr-dev \
|
libtbb2 libtbb-dev libdc1394-22-dev libopenexr-dev \
|
||||||
libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev \
|
libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev \
|
||||||
# sqlite3 dependencies
|
# sqlite3 dependencies
|
||||||
tclsh \
|
tclsh \
|
||||||
@ -171,15 +164,13 @@ RUN apt-get -qq update \
|
|||||||
gcc gfortran libopenblas-dev liblapack-dev && \
|
gcc gfortran libopenblas-dev liblapack-dev && \
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1
|
# Ensure python3 defaults to python3.9
|
||||||
|
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.9 1
|
||||||
|
|
||||||
RUN wget -q https://bootstrap.pypa.io/get-pip.py -O get-pip.py \
|
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"
|
&& python3 get-pip.py "pip"
|
||||||
|
|
||||||
COPY docker/main/requirements.txt /requirements.txt
|
COPY docker/main/requirements.txt /requirements.txt
|
||||||
COPY docker/main/requirements-dev.txt /requirements-dev.txt
|
|
||||||
|
|
||||||
RUN pip3 install -r /requirements.txt
|
RUN pip3 install -r /requirements.txt
|
||||||
|
|
||||||
# Build pysqlite3 from source
|
# Build pysqlite3 from source
|
||||||
@ -187,14 +178,8 @@ COPY docker/main/build_pysqlite3.sh /build_pysqlite3.sh
|
|||||||
RUN /build_pysqlite3.sh
|
RUN /build_pysqlite3.sh
|
||||||
|
|
||||||
COPY docker/main/requirements-wheels.txt /requirements-wheels.txt
|
COPY docker/main/requirements-wheels.txt /requirements-wheels.txt
|
||||||
RUN pip3 wheel --wheel-dir=/wheels -r /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
|
# Collect deps in a single layer
|
||||||
FROM scratch AS deps-rootfs
|
FROM scratch AS deps-rootfs
|
||||||
@ -205,14 +190,12 @@ COPY --from=libusb-build /usr/local/lib /usr/local/lib
|
|||||||
COPY --from=tempio /rootfs/ /
|
COPY --from=tempio /rootfs/ /
|
||||||
COPY --from=s6-overlay /rootfs/ /
|
COPY --from=s6-overlay /rootfs/ /
|
||||||
COPY --from=models /rootfs/ /
|
COPY --from=models /rootfs/ /
|
||||||
COPY --from=wheels /rootfs/ /
|
|
||||||
COPY docker/main/rootfs/ /
|
COPY docker/main/rootfs/ /
|
||||||
|
|
||||||
|
|
||||||
# Frigate deps (ffmpeg, python, nginx, go2rtc, s6-overlay, etc)
|
# Frigate deps (ffmpeg, python, nginx, go2rtc, s6-overlay, etc)
|
||||||
FROM slim-base AS deps
|
FROM slim-base AS deps
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
ARG BASE_IMAGE
|
|
||||||
|
|
||||||
ARG DEBIAN_FRONTEND
|
ARG DEBIAN_FRONTEND
|
||||||
# http://stackoverflow.com/questions/48162574/ddg#49462622
|
# http://stackoverflow.com/questions/48162574/ddg#49462622
|
||||||
@ -231,35 +214,16 @@ ENV TRANSFORMERS_NO_ADVISORY_WARNINGS=1
|
|||||||
# Set OpenCV ffmpeg loglevel to fatal: https://ffmpeg.org/doxygen/trunk/log_8h.html
|
# Set OpenCV ffmpeg loglevel to fatal: https://ffmpeg.org/doxygen/trunk/log_8h.html
|
||||||
ENV OPENCV_FFMPEG_LOGLEVEL=8
|
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}"
|
ENV PATH="/usr/local/go2rtc/bin:/usr/local/tempio/bin:/usr/local/nginx/sbin:${PATH}"
|
||||||
|
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
RUN --mount=type=bind,source=docker/main/install_deps.sh,target=/deps/install_deps.sh \
|
RUN --mount=type=bind,source=docker/main/install_deps.sh,target=/deps/install_deps.sh \
|
||||||
/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 \
|
RUN --mount=type=bind,from=wheels,source=/wheels,target=/deps/wheels \
|
||||||
|
python3 -m pip install --upgrade pip && \
|
||||||
pip3 install -U /deps/wheels/*.whl
|
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 / /
|
COPY --from=deps-rootfs / /
|
||||||
|
|
||||||
RUN ldconfig
|
RUN ldconfig
|
||||||
@ -277,12 +241,12 @@ ENTRYPOINT ["/init"]
|
|||||||
CMD []
|
CMD []
|
||||||
|
|
||||||
HEALTHCHECK --start-period=300s --start-interval=5s --interval=15s --timeout=5s --retries=3 \
|
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
|
CMD curl --fail --silent --show-error http://127.0.0.1:5000/api/version || exit 1
|
||||||
|
|
||||||
# Frigate deps with Node.js and NPM for devcontainer
|
# Frigate deps with Node.js and NPM for devcontainer
|
||||||
FROM deps AS devcontainer
|
FROM deps AS devcontainer
|
||||||
|
|
||||||
# Do not start the actual Frigate service on devcontainer as it will be started by VS Code
|
# Do not start the actual Frigate service on devcontainer as it will be started by VSCode
|
||||||
# But start a fake service for simulating the logs
|
# But start a fake service for simulating the logs
|
||||||
COPY docker/main/fake_frigate_run /etc/s6-overlay/s6-rc.d/frigate/run
|
COPY docker/main/fake_frigate_run /etc/s6-overlay/s6-rc.d/frigate/run
|
||||||
|
|
||||||
|
|||||||
@ -2,22 +2,16 @@
|
|||||||
|
|
||||||
set -euxo pipefail
|
set -euxo pipefail
|
||||||
|
|
||||||
NGINX_VERSION="1.27.4"
|
NGINX_VERSION="1.25.3"
|
||||||
VOD_MODULE_VERSION="1.31"
|
VOD_MODULE_VERSION="1.31"
|
||||||
SECURE_TOKEN_MODULE_VERSION="1.5"
|
SECURE_TOKEN_MODULE_VERSION="1.5"
|
||||||
SET_MISC_MODULE_VERSION="v0.33"
|
SET_MISC_MODULE_VERSION="v0.33"
|
||||||
NGX_DEVEL_KIT_VERSION="v0.3.3"
|
NGX_DEVEL_KIT_VERSION="v0.3.3"
|
||||||
|
|
||||||
source /etc/os-release
|
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
|
||||||
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 update
|
||||||
|
|
||||||
apt-get -yqq build-dep nginx
|
apt-get -yqq build-dep nginx
|
||||||
|
|
||||||
apt-get -yqq install --no-install-recommends ca-certificates wget
|
apt-get -yqq install --no-install-recommends ca-certificates wget
|
||||||
|
|||||||
@ -4,7 +4,7 @@ from openvino.tools import mo
|
|||||||
ov_model = mo.convert_model(
|
ov_model = mo.convert_model(
|
||||||
"/models/ssdlite_mobilenet_v2_coco_2018_05_09/frozen_inference_graph.pb",
|
"/models/ssdlite_mobilenet_v2_coco_2018_05_09/frozen_inference_graph.pb",
|
||||||
compress_to_fp16=True,
|
compress_to_fp16=True,
|
||||||
transformations_config="/usr/local/lib/python3.11/dist-packages/openvino/tools/mo/front/tf/ssd_v2_support.json",
|
transformations_config="/usr/local/lib/python3.9/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",
|
tensorflow_object_detection_api_pipeline_config="/models/ssdlite_mobilenet_v2_coco_2018_05_09/pipeline.config",
|
||||||
reverse_input_channels=True,
|
reverse_input_channels=True,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -2,31 +2,18 @@
|
|||||||
|
|
||||||
set -euxo pipefail
|
set -euxo pipefail
|
||||||
|
|
||||||
SQLITE3_VERSION="3.46.1"
|
SQLITE3_VERSION="96c92aba00c8375bc32fafcdf12429c58bd8aabfcadab6683e35bbb9cdebf19e" # 3.46.0
|
||||||
PYSQLITE3_VERSION="0.5.3"
|
PYSQLITE3_VERSION="0.5.3"
|
||||||
|
|
||||||
# Install libsqlite3-dev if not present (needed for some base images like NVIDIA TensorRT)
|
# Fetch the source code for the latest release of Sqlite.
|
||||||
if ! dpkg -l | grep -q libsqlite3-dev; then
|
|
||||||
echo "Installing libsqlite3-dev for compilation..."
|
|
||||||
apt-get update && apt-get install -y libsqlite3-dev && rm -rf /var/lib/apt/lists/*
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Fetch the pre-built sqlite amalgamation instead of building from source
|
|
||||||
if [[ ! -d "sqlite" ]]; then
|
if [[ ! -d "sqlite" ]]; then
|
||||||
mkdir sqlite
|
wget https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=${SQLITE3_VERSION} -O sqlite.tar.gz
|
||||||
cd sqlite
|
tar xzf sqlite.tar.gz
|
||||||
|
cd sqlite/
|
||||||
# Download the pre-built amalgamation from sqlite.org
|
LIBS="-lm" ./configure --disable-tcl --enable-tempstore=always
|
||||||
# For SQLite 3.46.1, the amalgamation version is 3460100
|
make sqlite3.c
|
||||||
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 ../
|
cd ../
|
||||||
|
rm sqlite.tar.gz
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Grab the pysqlite3 source code.
|
# Grab the pysqlite3 source code.
|
||||||
|
|||||||
@ -4,15 +4,8 @@ set -euxo pipefail
|
|||||||
|
|
||||||
SQLITE_VEC_VERSION="0.1.3"
|
SQLITE_VEC_VERSION="0.1.3"
|
||||||
|
|
||||||
source /etc/os-release
|
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
|
||||||
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 update
|
||||||
apt-get -yqq build-dep sqlite3 gettext git
|
apt-get -yqq build-dep sqlite3 gettext git
|
||||||
|
|
||||||
|
|||||||
@ -6,127 +6,92 @@ apt-get -qq update
|
|||||||
|
|
||||||
apt-get -qq install --no-install-recommends -y \
|
apt-get -qq install --no-install-recommends -y \
|
||||||
apt-transport-https \
|
apt-transport-https \
|
||||||
ca-certificates \
|
|
||||||
gnupg \
|
gnupg \
|
||||||
wget \
|
wget \
|
||||||
lbzip2 \
|
lbzip2 \
|
||||||
procps vainfo \
|
procps vainfo \
|
||||||
unzip locales tzdata libxml2 xz-utils \
|
unzip locales tzdata libxml2 xz-utils \
|
||||||
python3.11 \
|
python3.9 \
|
||||||
|
python3-pip \
|
||||||
curl \
|
curl \
|
||||||
lsof \
|
lsof \
|
||||||
jq \
|
jq \
|
||||||
nethogs \
|
nethogs
|
||||||
libgl1 \
|
|
||||||
libglib2.0-0 \
|
|
||||||
libusb-1.0.0 \
|
|
||||||
python3-h2 \
|
|
||||||
libgomp1 # memryx detector
|
|
||||||
|
|
||||||
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1
|
# ensure python3 defaults to python3.9
|
||||||
|
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.9 1
|
||||||
|
|
||||||
mkdir -p -m 600 /root/.gnupg
|
mkdir -p -m 600 /root/.gnupg
|
||||||
|
|
||||||
# install coral runtime
|
# add coral repo
|
||||||
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"
|
curl -fsSLo - https://packages.cloud.google.com/apt/doc/apt-key.gpg | \
|
||||||
unset DEBIAN_FRONTEND
|
gpg --dearmor -o /etc/apt/trusted.gpg.d/google-cloud-packages-archive-keyring.gpg
|
||||||
yes | dpkg -i /tmp/libedgetpu1-max.deb && export DEBIAN_FRONTEND=noninteractive
|
echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | tee /etc/apt/sources.list.d/coral-edgetpu.list
|
||||||
rm /tmp/libedgetpu1-max.deb
|
echo "libedgetpu1-max libedgetpu/accepted-eula select true" | debconf-set-selections
|
||||||
|
|
||||||
# install mesa-teflon-delegate from bookworm-backports
|
# enable non-free repo in Debian
|
||||||
# Only available for arm64 at the moment
|
if grep -q "Debian" /etc/issue; then
|
||||||
if [[ "${TARGETARCH}" == "arm64" ]]; then
|
sed -i -e's/ main/ main contrib non-free/g' /etc/apt/sources.list
|
||||||
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
|
fi
|
||||||
|
|
||||||
# ffmpeg -> amd64
|
# 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
|
||||||
if [[ "${TARGETARCH}" == "amd64" ]]; then
|
if [[ "${TARGETARCH}" == "amd64" ]]; then
|
||||||
mkdir -p /usr/lib/ffmpeg/5.0
|
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
|
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"
|
wget -qO btbn-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/7.0 --strip-components 1 amd64/bin/ffmpeg amd64/bin/ffprobe
|
tar -xf btbn-ffmpeg.tar.xz -C /usr/lib/ffmpeg/5.0 --strip-components 1
|
||||||
rm -rf ffmpeg.tar.xz
|
rm -rf btbn-ffmpeg.tar.xz /usr/lib/ffmpeg/5.0/doc /usr/lib/ffmpeg/5.0/bin/ffplay
|
||||||
|
wget -qO btbn-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 btbn-ffmpeg.tar.xz -C /usr/lib/ffmpeg/7.0 --strip-components 1
|
||||||
|
rm -rf btbn-ffmpeg.tar.xz /usr/lib/ffmpeg/7.0/doc /usr/lib/ffmpeg/7.0/bin/ffplay
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ffmpeg -> arm64
|
# ffmpeg -> arm64
|
||||||
if [[ "${TARGETARCH}" == "arm64" ]]; then
|
if [[ "${TARGETARCH}" == "arm64" ]]; then
|
||||||
mkdir -p /usr/lib/ffmpeg/5.0
|
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
|
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"
|
wget -qO btbn-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/7.0 --strip-components 1 arm64/bin/ffmpeg arm64/bin/ffprobe
|
tar -xf btbn-ffmpeg.tar.xz -C /usr/lib/ffmpeg/5.0 --strip-components 1
|
||||||
rm -f ffmpeg.tar.xz
|
rm -rf btbn-ffmpeg.tar.xz /usr/lib/ffmpeg/5.0/doc /usr/lib/ffmpeg/5.0/bin/ffplay
|
||||||
|
wget -qO btbn-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 btbn-ffmpeg.tar.xz -C /usr/lib/ffmpeg/7.0 --strip-components 1
|
||||||
|
rm -rf btbn-ffmpeg.tar.xz /usr/lib/ffmpeg/7.0/doc /usr/lib/ffmpeg/7.0/bin/ffplay
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# arch specific packages
|
# arch specific packages
|
||||||
if [[ "${TARGETARCH}" == "amd64" ]]; then
|
if [[ "${TARGETARCH}" == "amd64" ]]; then
|
||||||
# Install non-free version of i965 driver
|
# use debian bookworm for amd / intel-i965 driver packages
|
||||||
sed -i -E "/^Components: main$/s/main/main contrib non-free non-free-firmware/" "/etc/apt/sources.list.d/debian.sources" \
|
echo 'deb https://deb.debian.org/debian bookworm main contrib non-free' >/etc/apt/sources.list.d/debian-bookworm.list
|
||||||
&& apt-get -qq update \
|
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 \
|
apt-get -qq install --no-install-recommends --no-install-suggests -y \
|
||||||
intel-gpu-tools onevpl-tools \
|
i965-va-driver intel-gpu-tools onevpl-tools \
|
||||||
libva-drm2 \
|
libva-drm2 \
|
||||||
mesa-va-drivers radeontop
|
mesa-va-drivers radeontop
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
# intel packages use zst compression so we need to update dpkg
|
# intel packages use zst compression so we need to update dpkg
|
||||||
apt-get install -y dpkg
|
apt-get install -y dpkg
|
||||||
|
|
||||||
|
rm -f /etc/apt/sources.list.d/debian-bookworm.list
|
||||||
|
|
||||||
# use intel apt intel packages
|
# 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
|
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
|
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 update
|
||||||
apt-get -qq install --no-install-recommends --no-install-suggests -y \
|
apt-get -qq install --no-install-recommends --no-install-suggests -y \
|
||||||
intel-media-va-driver-non-free libmfx1 libmfxgen1 libvpl2
|
intel-opencl-icd=24.35.30872.31-996~22.04 intel-level-zero-gpu=1.3.29735.27-914~22.04 intel-media-va-driver-non-free=24.3.3-996~22.04 \
|
||||||
|
libmfx1=23.2.2-880~22.04 libmfxgen1=24.2.4-914~22.04 libvpl2=1:2.13.0.0-996~22.04
|
||||||
apt-get -qq install -y ocl-icd-libopencl1
|
|
||||||
|
|
||||||
# install libtbb12 for NPU support
|
|
||||||
apt-get -qq install -y libtbb12
|
|
||||||
|
|
||||||
rm -f /usr/share/keyrings/intel-graphics.gpg
|
rm -f /usr/share/keyrings/intel-graphics.gpg
|
||||||
rm -f /etc/apt/sources.list.d/intel-gpu-jammy.list
|
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
|
|
||||||
# npu packages
|
|
||||||
wget https://github.com/oneapi-src/level-zero/releases/download/v1.21.9/level-zero_1.21.9+u22.04_amd64.deb
|
|
||||||
wget https://github.com/intel/linux-npu-driver/releases/download/v1.17.0/intel-driver-compiler-npu_1.17.0.20250508-14912879441_ubuntu22.04_amd64.deb
|
|
||||||
wget https://github.com/intel/linux-npu-driver/releases/download/v1.17.0/intel-fw-npu_1.17.0.20250508-14912879441_ubuntu22.04_amd64.deb
|
|
||||||
wget https://github.com/intel/linux-npu-driver/releases/download/v1.17.0/intel-level-zero-npu_1.17.0.20250508-14912879441_ubuntu22.04_amd64.deb
|
|
||||||
|
|
||||||
dpkg -i *.deb
|
|
||||||
rm *.deb
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "${TARGETARCH}" == "arm64" ]]; then
|
if [[ "${TARGETARCH}" == "arm64" ]]; then
|
||||||
@ -145,6 +110,6 @@ rm -rf /var/lib/apt/lists/*
|
|||||||
|
|
||||||
# Install yq, for frigate-prepare and go2rtc echo source
|
# Install yq, for frigate-prepare and go2rtc echo source
|
||||||
curl -fsSL \
|
curl -fsSL \
|
||||||
"https://github.com/mikefarah/yq/releases/download/v4.48.2/yq_linux_$(dpkg --print-architecture)" \
|
"https://github.com/mikefarah/yq/releases/download/v4.33.3/yq_linux_$(dpkg --print-architecture)" \
|
||||||
--output /usr/local/bin/yq
|
--output /usr/local/bin/yq
|
||||||
chmod +x /usr/local/bin/yq
|
chmod +x /usr/local/bin/yq
|
||||||
|
|||||||
@ -1,14 +0,0 @@
|
|||||||
#!/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"
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Download the MxAccl for Frigate github release
|
|
||||||
wget https://github.com/memryx/mx_accl_frigate/archive/refs/tags/v2.1.0.zip -O /tmp/mxaccl.zip
|
|
||||||
unzip /tmp/mxaccl.zip -d /tmp
|
|
||||||
mv /tmp/mx_accl_frigate-2.1.0 /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
|
set -euxo pipefail
|
||||||
|
|
||||||
s6_version="3.2.1.0"
|
s6_version="3.1.5.0"
|
||||||
|
|
||||||
if [[ "${TARGETARCH}" == "amd64" ]]; then
|
if [[ "${TARGETARCH}" == "amd64" ]]; then
|
||||||
s6_arch="x86_64"
|
s6_arch="x86_64"
|
||||||
|
|||||||
@ -1,4 +1 @@
|
|||||||
ruff
|
ruff
|
||||||
|
|
||||||
# types
|
|
||||||
types-peewee == 3.17.*
|
|
||||||
|
|||||||
@ -1,85 +1,47 @@
|
|||||||
aiofiles == 24.1.*
|
|
||||||
click == 8.1.*
|
click == 8.1.*
|
||||||
# FastAPI
|
# FastAPI
|
||||||
aiohttp == 3.12.*
|
aiohttp == 3.11.2
|
||||||
starlette == 0.47.*
|
starlette == 0.41.2
|
||||||
starlette-context == 0.4.*
|
starlette-context == 0.3.6
|
||||||
fastapi[standard-no-fastapi-cloud-cli] == 0.116.*
|
fastapi == 0.115.*
|
||||||
uvicorn == 0.35.*
|
uvicorn == 0.30.*
|
||||||
slowapi == 0.1.*
|
slowapi == 0.1.*
|
||||||
joserfc == 1.2.*
|
imutils == 0.5.*
|
||||||
cryptography == 44.0.*
|
joserfc == 1.0.*
|
||||||
pathvalidate == 3.3.*
|
pathvalidate == 3.2.*
|
||||||
markupsafe == 3.0.*
|
markupsafe == 2.1.*
|
||||||
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
|
mypy == 1.6.1
|
||||||
onvif-zeep-async == 4.0.*
|
numpy == 1.26.*
|
||||||
|
onvif_zeep == 0.2.12
|
||||||
|
opencv-python-headless == 4.9.0.*
|
||||||
paho-mqtt == 2.1.*
|
paho-mqtt == 2.1.*
|
||||||
pandas == 2.2.*
|
pandas == 2.2.*
|
||||||
peewee == 3.17.*
|
peewee == 3.17.*
|
||||||
peewee_migrate == 1.13.*
|
peewee_migrate == 1.13.*
|
||||||
psutil == 7.1.*
|
psutil == 6.1.*
|
||||||
pydantic == 2.10.*
|
pydantic == 2.8.*
|
||||||
git+https://github.com/fbcotter/py3nvml#egg=py3nvml
|
git+https://github.com/fbcotter/py3nvml#egg=py3nvml
|
||||||
pytz == 2025.*
|
pytz == 2024.*
|
||||||
pyzmq == 26.2.*
|
pyzmq == 26.2.*
|
||||||
ruamel.yaml == 0.18.*
|
ruamel.yaml == 0.18.*
|
||||||
tzlocal == 5.2
|
tzlocal == 5.2
|
||||||
requests == 2.32.*
|
requests == 2.32.*
|
||||||
types-requests == 2.32.*
|
types-requests == 2.32.*
|
||||||
norfair == 2.3.*
|
scipy == 1.13.*
|
||||||
|
norfair == 2.2.*
|
||||||
setproctitle == 1.3.*
|
setproctitle == 1.3.*
|
||||||
ws4py == 0.5.*
|
ws4py == 0.5.*
|
||||||
unidecode == 1.3.*
|
unidecode == 1.3.*
|
||||||
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 & ONNX
|
||||||
openvino == 2025.3.*
|
openvino == 2024.3.*
|
||||||
onnxruntime == 1.22.*
|
onnxruntime-openvino == 1.19.* ; platform_machine == 'x86_64'
|
||||||
|
onnxruntime == 1.19.* ; platform_machine == 'aarch64'
|
||||||
# Embeddings
|
# Embeddings
|
||||||
transformers == 4.45.*
|
transformers == 4.45.*
|
||||||
# Generative AI
|
# Generative AI
|
||||||
google-generativeai == 0.8.*
|
google-generativeai == 0.8.*
|
||||||
ollama == 0.5.*
|
ollama == 0.3.*
|
||||||
openai == 1.65.*
|
openai == 1.51.*
|
||||||
# push notifications
|
# push notifications
|
||||||
py-vapid == 1.9.*
|
py-vapid == 1.9.*
|
||||||
pywebpush == 2.0.*
|
pywebpush == 2.0.*
|
||||||
# alpr
|
|
||||||
pyclipper == 1.3.*
|
|
||||||
shapely == 2.0.*
|
|
||||||
rapidfuzz==3.12.*
|
|
||||||
# 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.*
|
|
||||||
# Memory profiling
|
|
||||||
memray == 1.15.*
|
|
||||||
|
|||||||
@ -1 +1,2 @@
|
|||||||
scikit-build == 0.18.*
|
scikit-build == 0.17.*
|
||||||
|
nvidia-pyindex
|
||||||
|
|||||||
@ -10,7 +10,7 @@ echo "[INFO] Starting certsync..."
|
|||||||
|
|
||||||
lefile="/etc/letsencrypt/live/frigate/fullchain.pem"
|
lefile="/etc/letsencrypt/live/frigate/fullchain.pem"
|
||||||
|
|
||||||
tls_enabled=`python3 /usr/local/nginx/get_listen_settings.py | jq -r .tls.enabled`
|
tls_enabled=`python3 /usr/local/nginx/get_tls_settings.py | jq -r .enabled`
|
||||||
|
|
||||||
while true
|
while true
|
||||||
do
|
do
|
||||||
|
|||||||
@ -4,26 +4,52 @@
|
|||||||
|
|
||||||
set -o errexit -o nounset -o pipefail
|
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
|
# Logs should be sent to stdout so that s6 can collect them
|
||||||
|
|
||||||
# Tell S6-Overlay not to restart this service
|
# Tell S6-Overlay not to restart this service
|
||||||
s6-svc -O .
|
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
|
||||||
|
# Frigate will create the config file on startup
|
||||||
|
return 0
|
||||||
|
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() {
|
function set_libva_version() {
|
||||||
local ffmpeg_path
|
local ffmpeg_path=$(python3 /usr/local/ffmpeg/get_ffmpeg_path.py)
|
||||||
ffmpeg_path=$(python3 /usr/local/ffmpeg/get_ffmpeg_path.py)
|
export LIBAVFORMAT_VERSION_MAJOR=$($ffmpeg_path -version | grep -Po "libavformat\W+\K\d+")
|
||||||
LIBAVFORMAT_VERSION_MAJOR=$("$ffmpeg_path" -version | grep -Po "libavformat\W+\K\d+")
|
|
||||||
export LIBAVFORMAT_VERSION_MAJOR
|
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "[INFO] Preparing Frigate..."
|
echo "[INFO] Preparing Frigate..."
|
||||||
|
migrate_db_path
|
||||||
set_libva_version
|
set_libva_version
|
||||||
|
|
||||||
echo "[INFO] Starting Frigate..."
|
echo "[INFO] Starting Frigate..."
|
||||||
|
|
||||||
cd /opt/frigate || echo "[ERROR] Failed to change working directory to /opt/frigate"
|
cd /opt/frigate || echo "[ERROR] Failed to change working directory to /opt/frigate"
|
||||||
|
|||||||
@ -44,46 +44,10 @@ function get_ip_and_port_from_supervisor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function set_libva_version() {
|
function set_libva_version() {
|
||||||
local ffmpeg_path
|
local ffmpeg_path=$(python3 /usr/local/ffmpeg/get_ffmpeg_path.py)
|
||||||
ffmpeg_path=$(python3 /usr/local/ffmpeg/get_ffmpeg_path.py)
|
export LIBAVFORMAT_VERSION_MAJOR=$($ffmpeg_path -version | grep -Po "libavformat\W+\K\d+")
|
||||||
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
|
if [[ -f "/dev/shm/go2rtc.yaml" ]]; then
|
||||||
echo "[INFO] Removing stale config from last run..."
|
echo "[INFO] Removing stale config from last run..."
|
||||||
rm /dev/shm/go2rtc.yaml
|
rm /dev/shm/go2rtc.yaml
|
||||||
@ -93,7 +57,7 @@ if [[ ! -f "/dev/shm/go2rtc.yaml" ]]; then
|
|||||||
echo "[INFO] Preparing new go2rtc config..."
|
echo "[INFO] Preparing new go2rtc config..."
|
||||||
|
|
||||||
if [[ -n "${SUPERVISOR_TOKEN:-}" ]]; then
|
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
|
get_ip_and_port_from_supervisor
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -102,9 +66,7 @@ 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."
|
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
|
fi
|
||||||
|
|
||||||
# HomeKit configuration persistence setup
|
set_libva_version
|
||||||
readonly homekit_config_path="/config/go2rtc_homekit.yml"
|
|
||||||
setup_homekit_config "${homekit_config_path}"
|
|
||||||
|
|
||||||
readonly config_path="/config"
|
readonly config_path="/config"
|
||||||
|
|
||||||
@ -118,7 +80,5 @@ fi
|
|||||||
echo "[INFO] Starting go2rtc..."
|
echo "[INFO] Starting go2rtc..."
|
||||||
|
|
||||||
# Replace the bash process with the go2rtc process, redirecting stderr to stdout
|
# 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 2>&1
|
||||||
exec "${binary_path}" -config="${homekit_config_path}" -config=/dev/shm/go2rtc.yaml
|
exec "${binary_path}" -config=/dev/shm/go2rtc.yaml
|
||||||
|
|||||||
@ -79,13 +79,8 @@ if [ ! \( -f "$letsencrypt_path/privkey.pem" -a -f "$letsencrypt_path/fullchain.
|
|||||||
-keyout "$letsencrypt_path/privkey.pem" -out "$letsencrypt_path/fullchain.pem" 2>/dev/null
|
-keyout "$letsencrypt_path/privkey.pem" -out "$letsencrypt_path/fullchain.pem" 2>/dev/null
|
||||||
fi
|
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
|
# build templates for optional TLS support
|
||||||
python3 /usr/local/nginx/get_listen_settings.py | \
|
python3 /usr/local/nginx/get_tls_settings.py | \
|
||||||
tempio -template /usr/local/nginx/templates/listen.gotmpl \
|
tempio -template /usr/local/nginx/templates/listen.gotmpl \
|
||||||
-out /usr/local/nginx/conf/listen.conf
|
-out /usr/local/nginx/conf/listen.conf
|
||||||
|
|
||||||
|
|||||||
@ -1,146 +0,0 @@
|
|||||||
#!/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 +0,0 @@
|
|||||||
oneshot
|
|
||||||
@ -1 +0,0 @@
|
|||||||
/etc/s6-overlay/s6-rc.d/prepare/run
|
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
from ruamel.yaml import YAML
|
from ruamel.yaml import YAML
|
||||||
|
|
||||||
@ -9,28 +10,35 @@ from frigate.const import (
|
|||||||
DEFAULT_FFMPEG_VERSION,
|
DEFAULT_FFMPEG_VERSION,
|
||||||
INCLUDED_FFMPEG_VERSIONS,
|
INCLUDED_FFMPEG_VERSIONS,
|
||||||
)
|
)
|
||||||
from frigate.util.config import find_config_file
|
|
||||||
|
|
||||||
sys.path.remove("/opt/frigate")
|
sys.path.remove("/opt/frigate")
|
||||||
|
|
||||||
yaml = YAML()
|
yaml = YAML()
|
||||||
|
|
||||||
config_file = find_config_file()
|
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
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(config_file) as f:
|
with open(config_file) as f:
|
||||||
raw_config = f.read()
|
raw_config = f.read()
|
||||||
|
|
||||||
if config_file.endswith((".yaml", ".yml")):
|
if config_file.endswith((".yaml", ".yml")):
|
||||||
config: dict[str, Any] = yaml.load(raw_config)
|
config: dict[str, any] = yaml.load(raw_config)
|
||||||
elif config_file.endswith(".json"):
|
elif config_file.endswith(".json"):
|
||||||
config: dict[str, Any] = json.loads(raw_config)
|
config: dict[str, any] = json.loads(raw_config)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
config: dict[str, Any] = {}
|
config: dict[str, any] = {}
|
||||||
|
|
||||||
path = config.get("ffmpeg", {}).get("path", "default")
|
path = config.get("ffmpeg", {}).get("path", "default")
|
||||||
if path == "default":
|
if path == "default":
|
||||||
print(f"/usr/lib/ffmpeg/{DEFAULT_FFMPEG_VERSION}/bin/ffmpeg")
|
if shutil.which("ffmpeg") is None:
|
||||||
|
print(f"/usr/lib/ffmpeg/{DEFAULT_FFMPEG_VERSION}/bin/ffmpeg")
|
||||||
|
else:
|
||||||
|
print("ffmpeg")
|
||||||
elif path in INCLUDED_FFMPEG_VERSIONS:
|
elif path in INCLUDED_FFMPEG_VERSIONS:
|
||||||
print(f"/usr/lib/ffmpeg/{path}/bin/ffmpeg")
|
print(f"/usr/lib/ffmpeg/{path}/bin/ffmpeg")
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
from ruamel.yaml import YAML
|
from ruamel.yaml import YAML
|
||||||
|
|
||||||
@ -13,10 +13,8 @@ from frigate.const import (
|
|||||||
BIRDSEYE_PIPE,
|
BIRDSEYE_PIPE,
|
||||||
DEFAULT_FFMPEG_VERSION,
|
DEFAULT_FFMPEG_VERSION,
|
||||||
INCLUDED_FFMPEG_VERSIONS,
|
INCLUDED_FFMPEG_VERSIONS,
|
||||||
LIBAVFORMAT_VERSION_MAJOR,
|
|
||||||
)
|
)
|
||||||
from frigate.ffmpeg_presets import parse_preset_hardware_acceleration_encode
|
from frigate.ffmpeg_presets import parse_preset_hardware_acceleration_encode
|
||||||
from frigate.util.config import find_config_file
|
|
||||||
|
|
||||||
sys.path.remove("/opt/frigate")
|
sys.path.remove("/opt/frigate")
|
||||||
|
|
||||||
@ -31,20 +29,25 @@ if os.path.isdir("/run/secrets"):
|
|||||||
Path(os.path.join("/run/secrets", secret_file)).read_text().strip()
|
Path(os.path.join("/run/secrets", secret_file)).read_text().strip()
|
||||||
)
|
)
|
||||||
|
|
||||||
config_file = find_config_file()
|
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
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(config_file) as f:
|
with open(config_file) as f:
|
||||||
raw_config = f.read()
|
raw_config = f.read()
|
||||||
|
|
||||||
if config_file.endswith((".yaml", ".yml")):
|
if config_file.endswith((".yaml", ".yml")):
|
||||||
config: dict[str, Any] = yaml.load(raw_config)
|
config: dict[str, any] = yaml.load(raw_config)
|
||||||
elif config_file.endswith(".json"):
|
elif config_file.endswith(".json"):
|
||||||
config: dict[str, Any] = json.loads(raw_config)
|
config: dict[str, any] = json.loads(raw_config)
|
||||||
except FileNotFoundError:
|
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
|
# Need to enable CORS for go2rtc so the frigate integration / card work automatically
|
||||||
if go2rtc_config.get("api") is None:
|
if go2rtc_config.get("api") is None:
|
||||||
@ -54,7 +57,7 @@ elif go2rtc_config["api"].get("origin") is None:
|
|||||||
|
|
||||||
# Need to set default location for HA config
|
# Need to set default location for HA config
|
||||||
if go2rtc_config.get("hass") is None:
|
if go2rtc_config.get("hass") is None:
|
||||||
go2rtc_config["hass"] = {"config": "/homeassistant"}
|
go2rtc_config["hass"] = {"config": "/config"}
|
||||||
|
|
||||||
# we want to ensure that logs are easy to read
|
# we want to ensure that logs are easy to read
|
||||||
if go2rtc_config.get("log") is None:
|
if go2rtc_config.get("log") is None:
|
||||||
@ -63,34 +66,56 @@ elif go2rtc_config["log"].get("format") is None:
|
|||||||
go2rtc_config["log"]["format"] = "text"
|
go2rtc_config["log"]["format"] = "text"
|
||||||
|
|
||||||
# ensure there is a default webrtc config
|
# ensure there is a default webrtc config
|
||||||
if go2rtc_config.get("webrtc") is None:
|
if not go2rtc_config.get("webrtc"):
|
||||||
go2rtc_config["webrtc"] = {}
|
go2rtc_config["webrtc"] = {}
|
||||||
|
|
||||||
if go2rtc_config["webrtc"].get("candidates") is None:
|
# 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", []):
|
||||||
default_candidates = []
|
default_candidates = []
|
||||||
# use internal candidate if it was discovered when running through the add-on
|
# use internal candidate if it was discovered when running through the add-on
|
||||||
internal_candidate = os.environ.get("FRIGATE_GO2RTC_WEBRTC_CANDIDATE_INTERNAL")
|
internal_candidate = os.environ.get(
|
||||||
|
"FRIGATE_GO2RTC_WEBRTC_CANDIDATE_INTERNAL", None
|
||||||
|
)
|
||||||
if internal_candidate is not None:
|
if internal_candidate is not None:
|
||||||
default_candidates.append(internal_candidate)
|
default_candidates.append(internal_candidate)
|
||||||
# should set default stun server so webrtc can work
|
# should set default stun server so webrtc can work
|
||||||
default_candidates.append("stun:8555")
|
default_candidates.append("stun:8555")
|
||||||
|
|
||||||
go2rtc_config["webrtc"]["candidates"] = default_candidates
|
go2rtc_config["webrtc"] = {"candidates": default_candidates}
|
||||||
|
else:
|
||||||
if go2rtc_config.get("rtsp", {}).get("username") is not None:
|
print(
|
||||||
go2rtc_config["rtsp"]["username"] = go2rtc_config["rtsp"]["username"].format(
|
"[INFO] Not injecting WebRTC candidates into go2rtc config as it has been set manually",
|
||||||
**FRIGATE_ENV_VARS
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if go2rtc_config.get("rtsp", {}).get("password") is not None:
|
# sets default RTSP response to be equivalent to ?video=h264,h265&audio=aac
|
||||||
go2rtc_config["rtsp"]["password"] = go2rtc_config["rtsp"]["password"].format(
|
# this means user does not need to specify audio codec when using restream
|
||||||
**FRIGATE_ENV_VARS
|
# as source for frigate and the integration supports HLS playback
|
||||||
)
|
if go2rtc_config.get("rtsp") is None:
|
||||||
|
go2rtc_config["rtsp"] = {"default_query": "mp4"}
|
||||||
|
else:
|
||||||
|
if go2rtc_config["rtsp"].get("default_query") is None:
|
||||||
|
go2rtc_config["rtsp"]["default_query"] = "mp4"
|
||||||
|
|
||||||
|
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
|
||||||
|
)
|
||||||
|
|
||||||
# ensure ffmpeg path is set correctly
|
# ensure ffmpeg path is set correctly
|
||||||
path = config.get("ffmpeg", {}).get("path", "default")
|
path = config.get("ffmpeg", {}).get("path", "default")
|
||||||
if path == "default":
|
if path == "default":
|
||||||
ffmpeg_path = f"/usr/lib/ffmpeg/{DEFAULT_FFMPEG_VERSION}/bin/ffmpeg"
|
if shutil.which("ffmpeg") is None:
|
||||||
|
ffmpeg_path = f"/usr/lib/ffmpeg/{DEFAULT_FFMPEG_VERSION}/bin/ffmpeg"
|
||||||
|
else:
|
||||||
|
ffmpeg_path = "ffmpeg"
|
||||||
elif path in INCLUDED_FFMPEG_VERSIONS:
|
elif path in INCLUDED_FFMPEG_VERSIONS:
|
||||||
ffmpeg_path = f"/usr/lib/ffmpeg/{path}/bin/ffmpeg"
|
ffmpeg_path = f"/usr/lib/ffmpeg/{path}/bin/ffmpeg"
|
||||||
else:
|
else:
|
||||||
@ -102,12 +127,14 @@ elif go2rtc_config["ffmpeg"].get("bin") is None:
|
|||||||
go2rtc_config["ffmpeg"]["bin"] = ffmpeg_path
|
go2rtc_config["ffmpeg"]["bin"] = ffmpeg_path
|
||||||
|
|
||||||
# need to replace ffmpeg command when using ffmpeg4
|
# need to replace ffmpeg command when using ffmpeg4
|
||||||
if LIBAVFORMAT_VERSION_MAJOR < 59:
|
if int(os.environ.get("LIBAVFORMAT_VERSION_MAJOR", "59") or "59") < 59:
|
||||||
rtsp_args = "-fflags nobuffer -flags low_delay -stimeout 10000000 -user_agent go2rtc/ffmpeg -rtsp_transport tcp -i {input}"
|
if 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}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
if go2rtc_config.get("ffmpeg") is None:
|
if go2rtc_config.get("ffmpeg") is None:
|
||||||
go2rtc_config["ffmpeg"] = {"rtsp": rtsp_args}
|
go2rtc_config["ffmpeg"] = {"path": ""}
|
||||||
elif go2rtc_config["ffmpeg"].get("rtsp") is None:
|
|
||||||
go2rtc_config["ffmpeg"]["rtsp"] = rtsp_args
|
|
||||||
|
|
||||||
for name in go2rtc_config.get("streams", {}):
|
for name in go2rtc_config.get("streams", {}):
|
||||||
stream = go2rtc_config["streams"][name]
|
stream = go2rtc_config["streams"][name]
|
||||||
@ -135,7 +162,7 @@ for name in go2rtc_config.get("streams", {}):
|
|||||||
|
|
||||||
# add birdseye restream stream if enabled
|
# add birdseye restream stream if enabled
|
||||||
if config.get("birdseye", {}).get("restream", False):
|
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}"
|
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(ffmpeg_path, 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}')}"
|
||||||
|
|||||||
@ -1,16 +1,14 @@
|
|||||||
## Send a subrequest to verify if the user is authenticated and has permission to access the resource.
|
## Send a subrequest to verify if the user is authenticated and has permission to access the resource.
|
||||||
auth_request /auth;
|
auth_request /auth;
|
||||||
|
|
||||||
## Save the upstream metadata response headers from the auth request to variables
|
## Save the upstream metadata response headers from Authelia to variables.
|
||||||
auth_request_set $user $upstream_http_remote_user;
|
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 $groups $upstream_http_remote_groups;
|
||||||
auth_request_set $name $upstream_http_remote_name;
|
auth_request_set $name $upstream_http_remote_name;
|
||||||
auth_request_set $email $upstream_http_remote_email;
|
auth_request_set $email $upstream_http_remote_email;
|
||||||
|
|
||||||
## Inject the metadata response headers from the variables into the request made to the backend.
|
## 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-User $user;
|
||||||
proxy_set_header Remote-Role $role;
|
|
||||||
proxy_set_header Remote-Groups $groups;
|
proxy_set_header Remote-Groups $groups;
|
||||||
proxy_set_header Remote-Email $email;
|
proxy_set_header Remote-Email $email;
|
||||||
proxy_set_header Remote-Name $name;
|
proxy_set_header Remote-Name $name;
|
||||||
|
|||||||
@ -17,9 +17,7 @@ http {
|
|||||||
|
|
||||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
'$status $body_bytes_sent "$http_referer" '
|
'$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;
|
access_log /dev/stdout main;
|
||||||
|
|
||||||
@ -32,7 +30,7 @@ http {
|
|||||||
|
|
||||||
gzip on;
|
gzip on;
|
||||||
gzip_comp_level 6;
|
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;
|
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_proxied no-cache no-store private expired auth;
|
gzip_proxied no-cache no-store private expired auth;
|
||||||
gzip_vary on;
|
gzip_vary on;
|
||||||
|
|
||||||
@ -73,8 +71,6 @@ http {
|
|||||||
vod_manifest_segment_durations_mode accurate;
|
vod_manifest_segment_durations_mode accurate;
|
||||||
vod_ignore_edit_list on;
|
vod_ignore_edit_list on;
|
||||||
vod_segment_duration 10000;
|
vod_segment_duration 10000;
|
||||||
|
|
||||||
# MPEG-TS settings (not used when fMP4 is enabled, kept for reference)
|
|
||||||
vod_hls_mpegts_align_frames off;
|
vod_hls_mpegts_align_frames off;
|
||||||
vod_hls_mpegts_interleave_frames on;
|
vod_hls_mpegts_interleave_frames on;
|
||||||
|
|
||||||
@ -85,9 +81,6 @@ http {
|
|||||||
open_file_cache_errors on;
|
open_file_cache_errors on;
|
||||||
aio on;
|
aio on;
|
||||||
|
|
||||||
# file upload size
|
|
||||||
client_max_body_size 20M;
|
|
||||||
|
|
||||||
# https://github.com/kaltura/nginx-vod-module#vod_open_file_thread_pool
|
# https://github.com/kaltura/nginx-vod-module#vod_open_file_thread_pool
|
||||||
vod_open_file_thread_pool default;
|
vod_open_file_thread_pool default;
|
||||||
|
|
||||||
@ -100,17 +93,12 @@ http {
|
|||||||
gzip_types application/vnd.apple.mpegurl;
|
gzip_types application/vnd.apple.mpegurl;
|
||||||
|
|
||||||
include auth_location.conf;
|
include auth_location.conf;
|
||||||
include base_path.conf;
|
|
||||||
|
|
||||||
location /vod/ {
|
location /vod/ {
|
||||||
include auth_request.conf;
|
include auth_request.conf;
|
||||||
aio threads;
|
aio threads;
|
||||||
vod hls;
|
vod hls;
|
||||||
|
|
||||||
# Use fMP4 (fragmented MP4) instead of MPEG-TS for better performance
|
|
||||||
# Smaller segments, faster generation, better browser compatibility
|
|
||||||
vod_hls_container_format fmp4;
|
|
||||||
|
|
||||||
secure_token $args;
|
secure_token $args;
|
||||||
secure_token_types application/vnd.apple.mpegurl;
|
secure_token_types application/vnd.apple.mpegurl;
|
||||||
|
|
||||||
@ -118,14 +106,6 @@ http {
|
|||||||
expires off;
|
expires off;
|
||||||
|
|
||||||
keepalive_disable safari;
|
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/ {
|
location /stream/ {
|
||||||
@ -280,18 +260,6 @@ http {
|
|||||||
include proxy.conf;
|
include proxy.conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Allow unauthenticated access to the first_time_login endpoint
|
|
||||||
# so the login page can load help text before authentication.
|
|
||||||
location /api/auth/first_time_login {
|
|
||||||
auth_request off;
|
|
||||||
limit_except GET {
|
|
||||||
deny all;
|
|
||||||
}
|
|
||||||
rewrite ^/api(/.*)$ $1 break;
|
|
||||||
proxy_pass http://frigate_api;
|
|
||||||
include proxy.conf;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /api/stats {
|
location /api/stats {
|
||||||
include auth_request.conf;
|
include auth_request.conf;
|
||||||
access_log off;
|
access_log off;
|
||||||
@ -320,35 +288,11 @@ http {
|
|||||||
add_header Cache-Control "public";
|
add_header Cache-Control "public";
|
||||||
}
|
}
|
||||||
|
|
||||||
location /fonts/ {
|
|
||||||
access_log off;
|
|
||||||
expires 1y;
|
|
||||||
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 'href="/BASE_PATH/' 'href="$http_x_ingress_path/';
|
||||||
sub_filter 'url(/BASE_PATH/' 'url($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/dist/' '"$http_x_ingress_path/dist/';
|
||||||
sub_filter '"/BASE_PATH/js/' '"$http_x_ingress_path/js/';
|
sub_filter '"/BASE_PATH/js/' '"$http_x_ingress_path/js/';
|
||||||
sub_filter '"/BASE_PATH/assets/' '"$http_x_ingress_path/assets/';
|
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 '"/BASE_PATH/monacoeditorwork/' '"$http_x_ingress_path/assets/';
|
||||||
sub_filter 'return"/BASE_PATH/"' 'return window.baseUrl';
|
sub_filter 'return"/BASE_PATH/"' 'return window.baseUrl';
|
||||||
sub_filter '<body>' '<body><script>window.baseUrl="$http_x_ingress_path/";</script>';
|
sub_filter '<body>' '<body><script>window.baseUrl="$http_x_ingress_path/";</script>';
|
||||||
|
|||||||
@ -1,11 +0,0 @@
|
|||||||
"""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))
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
"""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))
|
|
||||||
30
docker/main/rootfs/usr/local/nginx/get_tls_settings.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
"""Prints the tls config as json to stdout."""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
from ruamel.yaml import YAML
|
||||||
|
|
||||||
|
yaml = YAML()
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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})
|
||||||
|
|
||||||
|
print(json.dumps(tls_config))
|
||||||
@ -1,19 +0,0 @@
|
|||||||
{{ 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 }}
|
|
||||||
@ -1,45 +1,33 @@
|
|||||||
|
# intended for internal traffic, not protected by auth
|
||||||
# Internal (IPv4 always; IPv6 optional)
|
|
||||||
listen 5000;
|
listen 5000;
|
||||||
{{ if .ipv6 }}{{ if .ipv6.enabled }}listen [::]:5000;{{ end }}{{ end }}
|
|
||||||
|
|
||||||
|
|
||||||
|
{{ if not .enabled }}
|
||||||
# intended for external traffic, protected by auth
|
# intended for external traffic, protected by auth
|
||||||
{{ if .tls }}
|
listen 8971;
|
||||||
{{ 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 }}
|
{{ else }}
|
||||||
# (No tls section) default to HTTP (IPv4 always; IPv6 optional)
|
# intended for external traffic, protected by auth
|
||||||
listen 8971;
|
listen 8971 ssl;
|
||||||
{{ if .ipv6 }}{{ if .ipv6.enabled }}listen [::]:8971;{{ 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;
|
||||||
|
}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
|||||||
@ -1,44 +0,0 @@
|
|||||||
#!/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 specific SDK 2.1 packages
|
|
||||||
echo "Installing MemryX SDK 2.1 packages..."
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y memx-drivers=2.1.* memx-accl=2.1.* mxa-manager=2.1.*
|
|
||||||
|
|
||||||
# Hold packages to prevent automatic upgrades
|
|
||||||
sudo apt-mark hold memx-drivers memx-accl mxa-manager
|
|
||||||
|
|
||||||
# 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"
|
|
||||||
|
|
||||||
echo "MemryX SDK 2.1 installation complete!"
|
|
||||||
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
./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
|
|
||||||
|
Before Width: | Height: | Size: 207 KiB |
|
Before Width: | Height: | Size: 209 KiB |
|
Before Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 201 KiB |
|
Before Width: | Height: | Size: 233 KiB |
|
Before Width: | Height: | Size: 242 KiB |
|
Before Width: | Height: | Size: 230 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 272 KiB |
|
Before Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 166 KiB |
|
Before Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 203 KiB |
|
Before Width: | Height: | Size: 110 KiB |
@ -3,36 +3,25 @@
|
|||||||
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
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
|
FROM wheels as rk-wheels
|
||||||
COPY docker/main/requirements-wheels.txt /requirements-wheels.txt
|
COPY docker/main/requirements-wheels.txt /requirements-wheels.txt
|
||||||
COPY docker/rockchip/requirements-wheels-rk.txt /requirements-wheels-rk.txt
|
COPY docker/rockchip/requirements-wheels-rk.txt /requirements-wheels-rk.txt
|
||||||
RUN sed -i "/https:\/\//d" /requirements-wheels.txt
|
RUN sed -i "/https:\/\//d" /requirements-wheels.txt
|
||||||
RUN sed -i "/onnxruntime/d" /requirements-wheels.txt
|
RUN pip3 wheel --wheel-dir=/rk-wheels -c /requirements-wheels.txt -r /requirements-wheels-rk.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
|
FROM deps AS rk-frigate
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
ARG PIP_BREAK_SYSTEM_PACKAGES
|
|
||||||
|
|
||||||
RUN --mount=type=bind,from=rk-wheels,source=/rk-wheels,target=/deps/rk-wheels \
|
RUN --mount=type=bind,from=rk-wheels,source=/rk-wheels,target=/deps/rk-wheels \
|
||||||
pip3 install --no-deps -U /deps/rk-wheels/*.whl
|
pip3 install -U /deps/rk-wheels/*.whl
|
||||||
|
|
||||||
WORKDIR /opt/frigate/
|
WORKDIR /opt/frigate/
|
||||||
COPY --from=rootfs / /
|
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.3.2/librknnrt.so /usr/lib/
|
ADD https://github.com/MarcA711/rknn-toolkit2/releases/download/v2.0.0/librknnrt.so /usr/lib/
|
||||||
|
|
||||||
ADD --chmod=111 https://github.com/MarcA711/Rockchip-FFmpeg-Builds/releases/download/6.1-11/ffmpeg /usr/lib/ffmpeg/6.0/bin/
|
RUN rm -rf /usr/lib/btbn-ffmpeg/bin/ffmpeg
|
||||||
ADD --chmod=111 https://github.com/MarcA711/Rockchip-FFmpeg-Builds/releases/download/6.1-11/ffprobe /usr/lib/ffmpeg/6.0/bin/
|
RUN rm -rf /usr/lib/btbn-ffmpeg/bin/ffprobe
|
||||||
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/6.1-7/ffmpeg /usr/lib/ffmpeg/6.0/bin/
|
||||||
ADD --chmod=111 https://github.com/MarcA711/Rockchip-FFmpeg-Builds/releases/download/7.1-1/ffprobe /usr/lib/ffmpeg/7.0/bin/
|
ADD --chmod=111 https://github.com/MarcA711/Rockchip-FFmpeg-Builds/releases/download/6.1-7/ffprobe /usr/lib/ffmpeg/6.0/bin/
|
||||||
ENV DEFAULT_FFMPEG_VERSION="6.0"
|
ENV PATH="/usr/lib/ffmpeg/6.0/bin/:${PATH}"
|
||||||
ENV INCLUDED_FFMPEG_VERSIONS="${DEFAULT_FFMPEG_VERSION}:${INCLUDED_FFMPEG_VERSIONS}"
|
|
||||||
|
|||||||
@ -1,82 +0,0 @@
|
|||||||
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,2 +1 @@
|
|||||||
rknn-toolkit2 == 2.3.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-toolkit-lite2 == 2.3.2
|
|
||||||
@ -2,75 +2,96 @@
|
|||||||
|
|
||||||
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
ARG ROCM=1
|
ARG ROCM=5.7.3
|
||||||
|
ARG AMDGPU=gfx900
|
||||||
ARG HSA_OVERRIDE_GFX_VERSION
|
ARG HSA_OVERRIDE_GFX_VERSION
|
||||||
ARG HSA_OVERRIDE
|
ARG HSA_OVERRIDE
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
FROM wget AS rocm
|
FROM ubuntu:focal as rocm
|
||||||
|
|
||||||
ARG ROCM
|
ARG ROCM
|
||||||
|
|
||||||
RUN apt update -qq && \
|
RUN apt-get update && apt-get -y upgrade
|
||||||
apt install -y wget gpg && \
|
RUN apt-get -y install gnupg wget
|
||||||
wget -O rocm.deb https://repo.radeon.com/amdgpu-install/7.1.1/ubuntu/jammy/amdgpu-install_7.1.1.70101-1_all.deb && \
|
|
||||||
apt install -y ./rocm.deb && \
|
RUN mkdir --parents --mode=0755 /etc/apt/keyrings
|
||||||
apt update && \
|
|
||||||
apt install -qq -y rocm
|
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 hipfft roctracer
|
||||||
|
RUN apt-get -y install --no-install-recommends migraphx-dev
|
||||||
|
|
||||||
RUN mkdir -p /opt/rocm-dist/opt/rocm-$ROCM/lib
|
RUN mkdir -p /opt/rocm-dist/opt/rocm-$ROCM/lib
|
||||||
RUN cd /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* librocfft*.so* /opt/rocm-dist/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 cd /opt/rocm-dist/opt/ && ln -s rocm-$ROCM rocm
|
||||||
|
|
||||||
RUN mkdir -p /opt/rocm-dist/etc/ld.so.conf.d/
|
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
|
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
|
FROM deps AS deps-prelim
|
||||||
|
|
||||||
COPY docker/rocm/debian-backports.sources /etc/apt/sources.list.d/debian-backports.sources
|
# need this to install libnuma1
|
||||||
RUN apt-get update && \
|
RUN apt-get update
|
||||||
apt-get install -y libnuma1 && \
|
# no ugprade?!?!
|
||||||
apt-get install -qq -y -t bookworm-backports mesa-va-drivers mesa-vulkan-drivers && \
|
RUN apt-get -y install libnuma1
|
||||||
# Install C++ standard library headers for HIPRTC kernel compilation fallback
|
|
||||||
apt-get install -qq -y libstdc++-12-dev && \
|
|
||||||
rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
WORKDIR /opt/frigate
|
WORKDIR /opt/frigate/
|
||||||
COPY --from=rootfs / /
|
COPY --from=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
|
COPY docker/rocm/requirements-wheels-rocm.txt /requirements.txt
|
||||||
RUN pip3 uninstall -y onnxruntime \
|
RUN python3 -m pip install --upgrade pip \
|
||||||
|
&& pip3 uninstall -y onnxruntime-openvino \
|
||||||
&& pip3 install -r /requirements.txt
|
&& pip3 install -r /requirements.txt
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
FROM scratch AS rocm-dist
|
FROM scratch AS rocm-dist
|
||||||
|
|
||||||
ARG ROCM
|
ARG ROCM
|
||||||
|
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/bin/rocminfo /opt/rocm-$ROCM/bin/migraphx-driver /opt/rocm-$ROCM/bin/
|
||||||
# Copy MIOpen database files for gfx10xx and gfx11xx only (RDNA2/RDNA3)
|
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/*gfx10* /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/share/miopen/db/*gfx11* /opt/rocm-$ROCM/share/miopen/db/
|
COPY --from=rocm /opt/rocm-$ROCM/lib/rocblas/library/*$AMDGPU* /opt/rocm-$ROCM/lib/rocblas/library/
|
||||||
# Copy rocBLAS library files for gfx10xx and gfx11xx only
|
|
||||||
COPY --from=rocm /opt/rocm-$ROCM/lib/rocblas/library/*gfx10* /opt/rocm-$ROCM/lib/rocblas/library/
|
|
||||||
COPY --from=rocm /opt/rocm-$ROCM/lib/rocblas/library/*gfx11* /opt/rocm-$ROCM/lib/rocblas/library/
|
|
||||||
COPY --from=rocm /opt/rocm-dist/ /
|
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
|
FROM deps-prelim AS rocm-prelim-hsa-override0
|
||||||
ENV MIGRAPHX_DISABLE_MIOPEN_FUSION=1
|
|
||||||
ENV MIGRAPHX_DISABLE_SCHEDULE_PASS=1
|
ENV HSA_ENABLE_SDMA=0
|
||||||
ENV MIGRAPHX_DISABLE_REDUCE_FUSION=1
|
|
||||||
ENV MIGRAPHX_ENABLE_HIPRTC_WORKAROUNDS=1
|
|
||||||
|
|
||||||
COPY --from=rocm-dist / /
|
COPY --from=rocm-dist / /
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +0,0 @@
|
|||||||
Types: deb
|
|
||||||
URIs: http://deb.debian.org/debian
|
|
||||||
Suites: bookworm-backports
|
|
||||||
Components: main
|
|
||||||
Enabled: yes
|
|
||||||
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
|
|
||||||
26
docker/rocm/migraphx/CMakeLists.txt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
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
|
||||||
|
)
|
||||||
582
docker/rocm/migraphx/migraphx_py.cpp
Normal file
@ -0,0 +1,582 @@
|
|||||||
|
/*
|
||||||
|
* 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 +1 @@
|
|||||||
onnxruntime-migraphx @ https://github.com/NickM-27/frigate-onnxruntime-rocm/releases/download/v7.1.0/onnxruntime_migraphx-1.23.1-cp311-cp311-linux_x86_64.whl
|
onnxruntime-rocm @ https://github.com/NickM-27/frigate-onnxruntime-rocm/releases/download/v1.0.0/onnxruntime_rocm-1.17.3-cp39-cp39-linux_x86_64.whl
|
||||||
3
docker/rocm/rocm-pin-600
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Package: *
|
||||||
|
Pin: release o=repo.radeon.com
|
||||||
|
Pin-Priority: 600
|
||||||
@ -1,5 +1,8 @@
|
|||||||
|
variable "AMDGPU" {
|
||||||
|
default = "gfx900"
|
||||||
|
}
|
||||||
variable "ROCM" {
|
variable "ROCM" {
|
||||||
default = "7.1.1"
|
default = "5.7.3"
|
||||||
}
|
}
|
||||||
variable "HSA_OVERRIDE_GFX_VERSION" {
|
variable "HSA_OVERRIDE_GFX_VERSION" {
|
||||||
default = ""
|
default = ""
|
||||||
@ -7,13 +10,6 @@ variable "HSA_OVERRIDE_GFX_VERSION" {
|
|||||||
variable "HSA_OVERRIDE" {
|
variable "HSA_OVERRIDE" {
|
||||||
default = "1"
|
default = "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
target wget {
|
|
||||||
dockerfile = "docker/main/Dockerfile"
|
|
||||||
platforms = ["linux/amd64"]
|
|
||||||
target = "wget"
|
|
||||||
}
|
|
||||||
|
|
||||||
target deps {
|
target deps {
|
||||||
dockerfile = "docker/main/Dockerfile"
|
dockerfile = "docker/main/Dockerfile"
|
||||||
platforms = ["linux/amd64"]
|
platforms = ["linux/amd64"]
|
||||||
@ -30,11 +26,11 @@ target rocm {
|
|||||||
dockerfile = "docker/rocm/Dockerfile"
|
dockerfile = "docker/rocm/Dockerfile"
|
||||||
contexts = {
|
contexts = {
|
||||||
deps = "target:deps",
|
deps = "target:deps",
|
||||||
wget = "target:wget",
|
|
||||||
rootfs = "target:rootfs"
|
rootfs = "target:rootfs"
|
||||||
}
|
}
|
||||||
platforms = ["linux/amd64"]
|
platforms = ["linux/amd64"]
|
||||||
args = {
|
args = {
|
||||||
|
AMDGPU = AMDGPU,
|
||||||
ROCM = ROCM,
|
ROCM = ROCM,
|
||||||
HSA_OVERRIDE_GFX_VERSION = HSA_OVERRIDE_GFX_VERSION,
|
HSA_OVERRIDE_GFX_VERSION = HSA_OVERRIDE_GFX_VERSION,
|
||||||
HSA_OVERRIDE = HSA_OVERRIDE
|
HSA_OVERRIDE = HSA_OVERRIDE
|
||||||
|
|||||||
1
docker/rocm/rocm.list
Normal file
@ -0,0 +1 @@
|
|||||||
|
deb [arch=amd64 signed-by=/etc/apt/keyrings/rocm.gpg] https://repo.radeon.com/rocm/apt/5.7.3 focal main
|
||||||
@ -1,15 +1,53 @@
|
|||||||
BOARDS += rocm
|
BOARDS += rocm
|
||||||
|
|
||||||
|
# AMD/ROCm is chunky so we build couple of smaller images for specific chipsets
|
||||||
|
ROCM_CHIPSETS:=gfx900:9.0.0 gfx1030:10.3.0 gfx1100:11.0.0
|
||||||
|
|
||||||
local-rocm: version
|
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 --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 \
|
docker buildx bake --file=docker/rocm/rocm.hcl rocm \
|
||||||
--set rocm.tags=frigate:latest-rocm \
|
--set rocm.tags=frigate:latest-rocm \
|
||||||
--load
|
--load
|
||||||
|
|
||||||
build-rocm: version
|
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 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 \
|
docker buildx bake --file=docker/rocm/rocm.hcl rocm \
|
||||||
--set rocm.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-rocm
|
--set rocm.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-rocm
|
||||||
|
|
||||||
push-rocm: build-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 --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 \
|
docker buildx bake --file=docker/rocm/rocm.hcl rocm \
|
||||||
--set rocm.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-rocm \
|
--set rocm.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-rocm \
|
||||||
--push
|
--push
|
||||||
|
|||||||
@ -6,12 +6,11 @@ ARG DEBIAN_FRONTEND=noninteractive
|
|||||||
FROM deps AS rpi-deps
|
FROM deps AS rpi-deps
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
|
|
||||||
|
RUN rm -rf /usr/lib/btbn-ffmpeg/
|
||||||
|
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
RUN --mount=type=bind,source=docker/rpi/install_deps.sh,target=/deps/install_deps.sh \
|
RUN --mount=type=bind,source=docker/rpi/install_deps.sh,target=/deps/install_deps.sh \
|
||||||
/deps/install_deps.sh
|
/deps/install_deps.sh
|
||||||
|
|
||||||
ENV DEFAULT_FFMPEG_VERSION="rpi"
|
|
||||||
ENV INCLUDED_FFMPEG_VERSIONS="${DEFAULT_FFMPEG_VERSION}:${INCLUDED_FFMPEG_VERSIONS}"
|
|
||||||
|
|
||||||
WORKDIR /opt/frigate/
|
WORKDIR /opt/frigate/
|
||||||
COPY --from=rootfs / /
|
COPY --from=rootfs / /
|
||||||
|
|||||||
@ -18,17 +18,13 @@ apt-get -qq install --no-install-recommends -y \
|
|||||||
mkdir -p -m 600 /root/.gnupg
|
mkdir -p -m 600 /root/.gnupg
|
||||||
|
|
||||||
# enable non-free repo
|
# enable non-free repo
|
||||||
echo "deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware" | tee -a /etc/apt/sources.list
|
sed -i -e's/ main/ main contrib non-free/g' /etc/apt/sources.list
|
||||||
apt update
|
|
||||||
|
|
||||||
# ffmpeg -> arm64
|
# ffmpeg -> arm64
|
||||||
if [[ "${TARGETARCH}" == "arm64" ]]; then
|
if [[ "${TARGETARCH}" == "arm64" ]]; then
|
||||||
# add raspberry pi repo
|
# add raspberry pi repo
|
||||||
gpg --no-default-keyring --keyring /usr/share/keyrings/raspbian.gpg --keyserver keyserver.ubuntu.com --recv-keys 82B129927FA3303E
|
gpg --no-default-keyring --keyring /usr/share/keyrings/raspbian.gpg --keyserver keyserver.ubuntu.com --recv-keys 82B129927FA3303E
|
||||||
echo "deb [signed-by=/usr/share/keyrings/raspbian.gpg] https://archive.raspberrypi.org/debian/ bookworm main" | tee /etc/apt/sources.list.d/raspi.list
|
echo "deb [signed-by=/usr/share/keyrings/raspbian.gpg] https://archive.raspberrypi.org/debian/ bullseye main" | tee /etc/apt/sources.list.d/raspi.list
|
||||||
apt-get -qq update
|
apt-get -qq update
|
||||||
apt-get -qq install --no-install-recommends --no-install-suggests -y ffmpeg
|
apt-get -qq install --no-install-recommends --no-install-suggests -y ffmpeg
|
||||||
mkdir -p /usr/lib/ffmpeg/rpi/bin
|
|
||||||
ln -svf /usr/bin/ffmpeg /usr/lib/ffmpeg/rpi/bin/ffmpeg
|
|
||||||
ln -svf /usr/bin/ffprobe /usr/lib/ffmpeg/rpi/bin/ffprobe
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@ -1,28 +0,0 @@
|
|||||||
# syntax=docker/dockerfile:1.6
|
|
||||||
|
|
||||||
# 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 synap1680-wheels
|
|
||||||
ARG TARGETARCH
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
RUN wget -qO- "https://github.com/GaryHuang-ASUS/synaptics_astra_sdk/releases/download/v1.5.0/Synaptics-SL1680-v1.5.0-rt.tar" | tar -C / -xzf -
|
|
||||||
RUN wget -P /wheels/ "https://github.com/synaptics-synap/synap-python/releases/download/v0.0.4-preview/synap_python-0.0.4-cp311-cp311-manylinux_2_35_aarch64.whl"
|
|
||||||
|
|
||||||
FROM deps AS synap1680-deps
|
|
||||||
ARG TARGETARCH
|
|
||||||
ARG PIP_BREAK_SYSTEM_PACKAGES
|
|
||||||
|
|
||||||
RUN --mount=type=bind,from=synap1680-wheels,source=/wheels,target=/deps/synap-wheels \
|
|
||||||
pip3 install --no-deps -U /deps/synap-wheels/*.whl
|
|
||||||
|
|
||||||
WORKDIR /opt/frigate/
|
|
||||||
COPY --from=rootfs / /
|
|
||||||
|
|
||||||
COPY --from=synap1680-wheels /rootfs/usr/local/lib/*.so /usr/lib
|
|
||||||
|
|
||||||
ADD https://raw.githubusercontent.com/synaptics-astra/synap-release/v1.5.0/models/dolphin/object_detection/coco/model/mobilenet224_full80/model.synap /synaptics/mobilenet.synap
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
target wheels {
|
|
||||||
dockerfile = "docker/main/Dockerfile"
|
|
||||||
platforms = ["linux/arm64"]
|
|
||||||
target = "wheels"
|
|
||||||
}
|
|
||||||
|
|
||||||
target deps {
|
|
||||||
dockerfile = "docker/main/Dockerfile"
|
|
||||||
platforms = ["linux/arm64"]
|
|
||||||
target = "deps"
|
|
||||||
}
|
|
||||||
|
|
||||||
target rootfs {
|
|
||||||
dockerfile = "docker/main/Dockerfile"
|
|
||||||
platforms = ["linux/arm64"]
|
|
||||||
target = "rootfs"
|
|
||||||
}
|
|
||||||
|
|
||||||
target synaptics {
|
|
||||||
dockerfile = "docker/synaptics/Dockerfile"
|
|
||||||
contexts = {
|
|
||||||
wheels = "target:wheels",
|
|
||||||
deps = "target:deps",
|
|
||||||
rootfs = "target:rootfs"
|
|
||||||
}
|
|
||||||
platforms = ["linux/arm64"]
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
BOARDS += synaptics
|
|
||||||
|
|
||||||
local-synaptics: version
|
|
||||||
docker buildx bake --file=docker/synaptics/synaptics.hcl synaptics \
|
|
||||||
--set synaptics.tags=frigate:latest-synaptics \
|
|
||||||
--load
|
|
||||||
|
|
||||||
build-synaptics: version
|
|
||||||
docker buildx bake --file=docker/synaptics/synaptics.hcl synaptics \
|
|
||||||
--set synaptics.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-synaptics
|
|
||||||
|
|
||||||
push-synaptics: build-synaptics
|
|
||||||
docker buildx bake --file=docker/synaptics/synaptics.hcl synaptics \
|
|
||||||
--set synaptics.tags=$(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-synaptics \
|
|
||||||
--push
|
|
||||||
@ -3,35 +3,32 @@
|
|||||||
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
# Globally set pip break-system-packages option to avoid having to specify it every time
|
# Make this a separate target so it can be built/cached optionally
|
||||||
ARG PIP_BREAK_SYSTEM_PACKAGES=1
|
FROM wheels as trt-wheels
|
||||||
|
ARG DEBIAN_FRONTEND
|
||||||
|
ARG TARGETARCH
|
||||||
|
|
||||||
FROM wheels AS trt-wheels
|
# Add TensorRT wheels to another folder
|
||||||
ARG PIP_BREAK_SYSTEM_PACKAGES
|
|
||||||
|
|
||||||
# Install TensorRT wheels
|
|
||||||
COPY docker/tensorrt/requirements-amd64.txt /requirements-tensorrt.txt
|
COPY docker/tensorrt/requirements-amd64.txt /requirements-tensorrt.txt
|
||||||
COPY docker/main/requirements-wheels.txt /requirements-wheels.txt
|
RUN mkdir -p /trt-wheels && pip3 wheel --wheel-dir=/trt-wheels -r /requirements-tensorrt.txt
|
||||||
|
|
||||||
# remove dependencies from the requirements that have type constraints
|
|
||||||
RUN sed -i '/\[.*\]/d' /requirements-wheels.txt \
|
|
||||||
&& pip3 wheel --wheel-dir=/trt-wheels -c /requirements-wheels.txt -r /requirements-tensorrt.txt
|
|
||||||
|
|
||||||
FROM deps AS frigate-tensorrt
|
|
||||||
ARG PIP_BREAK_SYSTEM_PACKAGES
|
|
||||||
|
|
||||||
|
FROM tensorrt-base AS frigate-tensorrt
|
||||||
|
ENV TRT_VER=8.5.3
|
||||||
RUN --mount=type=bind,from=trt-wheels,source=/trt-wheels,target=/deps/trt-wheels \
|
RUN --mount=type=bind,from=trt-wheels,source=/trt-wheels,target=/deps/trt-wheels \
|
||||||
pip3 uninstall -y onnxruntime \
|
pip3 install -U /deps/trt-wheels/*.whl && \
|
||||||
&& pip3 install -U /deps/trt-wheels/*.whl
|
ldconfig
|
||||||
|
|
||||||
COPY --from=rootfs / /
|
|
||||||
COPY docker/tensorrt/detector/rootfs/etc/ld.so.conf.d /etc/ld.so.conf.d
|
|
||||||
RUN ldconfig
|
|
||||||
|
|
||||||
|
ENV LD_LIBRARY_PATH=/usr/local/lib/python3.9/dist-packages/tensorrt:/usr/local/cuda/lib64:/usr/local/lib/python3.9/dist-packages/nvidia/cufft/lib
|
||||||
WORKDIR /opt/frigate/
|
WORKDIR /opt/frigate/
|
||||||
|
COPY --from=rootfs / /
|
||||||
|
|
||||||
# Dev Container w/ TRT
|
# Dev Container w/ TRT
|
||||||
FROM devcontainer AS devcontainer-trt
|
FROM devcontainer AS devcontainer-trt
|
||||||
|
|
||||||
|
COPY --from=trt-deps /usr/local/lib/libyolo_layer.so /usr/local/lib/libyolo_layer.so
|
||||||
|
COPY --from=trt-deps /usr/local/src/tensorrt_demos /usr/local/src/tensorrt_demos
|
||||||
|
COPY --from=trt-deps /usr/local/cuda-12.1 /usr/local/cuda
|
||||||
|
COPY docker/tensorrt/detector/rootfs/ /
|
||||||
|
COPY --from=trt-deps /usr/local/lib/libyolo_layer.so /usr/local/lib/libyolo_layer.so
|
||||||
RUN --mount=type=bind,from=trt-wheels,source=/trt-wheels,target=/deps/trt-wheels \
|
RUN --mount=type=bind,from=trt-wheels,source=/trt-wheels,target=/deps/trt-wheels \
|
||||||
pip3 install -U /deps/trt-wheels/*.whl
|
pip3 install -U /deps/trt-wheels/*.whl
|
||||||
|
|||||||