-
Notifications
You must be signed in to change notification settings - Fork 8
221 lines (205 loc) · 8.93 KB
/
Copy pathci.yml
File metadata and controls
221 lines (205 loc) · 8.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
name: CI
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.14"
- name: Install linters
run: pip install ruff 'black<26'
- name: Run ruff check
run: ruff check plugins/ tests/ utils/
- name: Run black check
run: black --check plugins/ tests/ utils/
build:
needs: lint
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.12", "3.14"]
exclude:
# ubuntu-latest is 24.04 with system Python 3.12;
# GStreamer gi bindings are built for 3.12 only
- os: ubuntu-latest
python-version: "3.14"
include:
- os: ubuntu-latest
gst-install: |
sudo apt-get update
sudo apt-get install -y \
gstreamer1.0-tools \
gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gir1.2-gstreamer-1.0 \
gir1.2-gst-plugins-base-1.0 \
gir1.2-gst-plugins-bad-1.0 \
libgstreamer-plugins-bad1.0-dev \
python3-gi \
python3-gi-cairo \
python3-gst-1.0 \
gstreamer1.0-python3-plugin-loader \
libcairo2 \
libcairo2-dev \
pkg-config \
libgirepository-2.0-dev \
libglib2.0-dev \
python3-dev
pip install numpy opencv-python-headless ultralytics onnxruntime
- os: macos-latest
gst-install: |
brew install gstreamer cairo pkg-config pygobject3 gobject-introspection
echo "DYLD_LIBRARY_PATH=$(brew --prefix)/lib:$DYLD_LIBRARY_PATH" >> $GITHUB_ENV
echo "GI_TYPELIB_PATH=$(brew --prefix)/lib/girepository-1.0" >> $GITHUB_ENV
- os: windows-latest
gst-install: |
choco install gstreamer gstreamer-devel --yes
"C:\gstreamer\1.0\msvc_x86_64\bin" >> $env:GITHUB_PATH
"GST_PLUGIN_PATH=C:\gstreamer\1.0\msvc_x86_64\lib\gstreamer-1.0" >> $env:GITHUB_ENV
"PKG_CONFIG_PATH=C:\gstreamer\1.0\msvc_x86_64\lib\pkgconfig" >> $env:GITHUB_ENV
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install GStreamer
run: ${{ matrix.gst-install }}
- name: Create venv and install CPU dependencies
shell: bash
run: |
python -m venv --system-site-packages .venv
if [[ "$RUNNER_OS" == "Windows" ]]; then
source .venv/Scripts/activate
else
source .venv/bin/activate
fi
pip install --no-deps -e .
pip install numpy opencv-python-headless ultralytics
# pygobject/pycairo from pip need C build deps; install only where available
pip install pygobject pycairo || echo "pygobject/pycairo pip install failed (using system packages)"
- name: Verify core imports
shell: bash
continue-on-error: true
run: |
if [[ "$RUNNER_OS" == "Windows" ]]; then
source .venv/Scripts/activate
else
source .venv/bin/activate
fi
python -c "
import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstBase', '1.0')
from gi.repository import Gst
Gst.init(None)
import importlib, sys
modules = [
'plugins.python.streammux',
'plugins.python.streamdemux',
'plugins.python.overlay',
'plugins.python.engine.ml_engine',
'plugins.python.engine.engine_factory',
]
failed = []
for m in modules:
try:
importlib.import_module(m)
print(f' OK {m}')
except Exception as e:
print(f' FAIL {m}: {e}')
failed.append(m)
if failed:
print(f'\n{len(failed)} import(s) failed')
sys.exit(1)
print('\nAll imports OK')
"
- name: Check GStreamer plugin discovery (Linux)
if: runner.os == 'Linux'
run: |
source .venv/bin/activate
VENV_SITE=$(python -c "import site; print(site.getsitepackages()[0])")
# libgstpython.so uses system Python which needs:
# - /usr/lib/python3/dist-packages for gi (python3-gi apt package)
# - venv site-packages for pip-installed ML packages
# - plugins/python for our GStreamer element modules
export PYTHONPATH="/usr/lib/python3/dist-packages:${VENV_SITE}:${{ github.workspace }}/plugins/python"
export GST_PLUGIN_PATH=${{ github.workspace }}/plugins
# Prevent hostedtoolcache libpython from shadowing system libpython
unset LD_LIBRARY_PATH
rm -rf ~/.cache/gstreamer-1.0
gst-inspect-1.0 python
gst-inspect-1.0 pyml_objectdetector
- name: ONNX pipeline smoke test (Linux)
if: runner.os == 'Linux'
run: |
source .venv/bin/activate
pip install onnxruntime
VENV_SITE=$(python -c "import site; print(site.getsitepackages()[0])")
export PYTHONPATH="/usr/lib/python3/dist-packages:${VENV_SITE}:${{ github.workspace }}/plugins/python"
export GST_PLUGIN_PATH=${{ github.workspace }}/plugins
unset LD_LIBRARY_PATH
rm -rf ~/.cache/gstreamer-1.0
# Export YOLO model to ONNX
python -c "from ultralytics import YOLO; YOLO('yolo11n.pt').export(format='onnx')"
# Run 2-frame smoke test with synthetic source (avoids codec deps)
gst-launch-1.0 videotestsrc num-buffers=2 \
! "video/x-raw,format=RGB,width=640,height=640" \
! pyml_objectdetector engine-name=onnx model-name=yolo11n.onnx device=cpu input-format=nchw post-process=anchor_free \
! fakesink
- name: ONNX pipeline smoke test (macOS)
if: runner.os == 'macOS'
run: |
# brew's libgstpython.dylib embeds brew's Python (not actions/setup-python).
# Install ML packages into brew's Python so libgstpython can find them.
BREW_PREFIX=$(brew --prefix)
BREW_PIP="${BREW_PREFIX}/bin/pip3"
BREW_PYTHON="${BREW_PREFIX}/bin/python3"
${BREW_PIP} install --break-system-packages ultralytics onnxruntime onnx numpy opencv-python-headless
export GST_PLUGIN_PATH=${{ github.workspace }}/plugins
export PYTHONPATH=${{ github.workspace }}/plugins/python
# Export YOLO model to ONNX
${BREW_PYTHON} -c "from ultralytics import YOLO; YOLO('yolo11n.pt').export(format='onnx')"
# Run 2-frame smoke test with synthetic source (avoids codec deps)
gst-launch-1.0 videotestsrc num-buffers=2 \
! "video/x-raw,format=RGB,width=640,height=640" \
! pyml_objectdetector engine-name=onnx model-name=yolo11n.onnx device=cpu input-format=nchw post-process=anchor_free \
! fakesink
- name: ONNX pipeline smoke test (Windows)
if: runner.os == 'Windows'
continue-on-error: true
shell: bash
run: |
source .venv/Scripts/activate
pip install onnxruntime
SITE_PKGS=$(python -c "import site; print(site.getsitepackages()[0])")
# Find GStreamer install location
GST_BIN=$(find /c/gstreamer -name "gst-launch-1.0.exe" 2>/dev/null | head -1 | xargs dirname)
if [[ -z "$GST_BIN" ]]; then
echo "ERROR: gst-launch-1.0.exe not found under /c/gstreamer"
find /c/gstreamer -type f -name "gst-*" 2>/dev/null || echo "No gst binaries found"
ls /c/gstreamer/ 2>/dev/null || echo "/c/gstreamer does not exist"
exit 1
fi
echo "Found GStreamer at: $GST_BIN"
export PATH="${GST_BIN}:$PATH"
GST_LIB=$(dirname "$GST_BIN")/lib/gstreamer-1.0
export GST_PLUGIN_PATH="${{ github.workspace }}/plugins;${GST_LIB}"
export PYTHONPATH="${SITE_PKGS};${{ github.workspace }}/plugins/python;$PYTHONPATH"
# Export YOLO model to ONNX
python -c "from ultralytics import YOLO; YOLO('yolo11n.pt').export(format='onnx')"
# Run 2-frame smoke test with synthetic source (avoids codec deps)
gst-launch-1.0.exe videotestsrc num-buffers=2 \
! "video/x-raw,format=RGB,width=640,height=640" \
! pyml_objectdetector engine-name=onnx model-name=yolo11n.onnx device=cpu input-format=nchw post-process=anchor_free \
! fakesink