cymedia 0.1.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cymedia-0.1.0a1/CHANGELOG.md +12 -0
- cymedia-0.1.0a1/LICENSE +21 -0
- cymedia-0.1.0a1/MANIFEST.in +4 -0
- cymedia-0.1.0a1/PKG-INFO +139 -0
- cymedia-0.1.0a1/README.md +111 -0
- cymedia-0.1.0a1/pyproject.toml +51 -0
- cymedia-0.1.0a1/setup.cfg +4 -0
- cymedia-0.1.0a1/setup.py +21 -0
- cymedia-0.1.0a1/src/cymedia/__init__.py +8 -0
- cymedia-0.1.0a1/src/cymedia/_core.pyx +391 -0
- cymedia-0.1.0a1/src/cymedia/_types.py +27 -0
- cymedia-0.1.0a1/src/cymedia/cymedia_sink.h +48 -0
- cymedia-0.1.0a1/src/cymedia/engine.c +922 -0
- cymedia-0.1.0a1/src/cymedia/engine.h +64 -0
- cymedia-0.1.0a1/src/cymedia/ladder.py +56 -0
- cymedia-0.1.0a1/src/cymedia/qsink.c +185 -0
- cymedia-0.1.0a1/src/cymedia/qsink.h +35 -0
- cymedia-0.1.0a1/src/cymedia.egg-info/PKG-INFO +139 -0
- cymedia-0.1.0a1/src/cymedia.egg-info/SOURCES.txt +24 -0
- cymedia-0.1.0a1/src/cymedia.egg-info/dependency_links.txt +1 -0
- cymedia-0.1.0a1/src/cymedia.egg-info/requires.txt +3 -0
- cymedia-0.1.0a1/src/cymedia.egg-info/top_level.txt +1 -0
- cymedia-0.1.0a1/tests/conftest.py +7 -0
- cymedia-0.1.0a1/tests/helpers.py +66 -0
- cymedia-0.1.0a1/tests/test_graph_cpu.py +103 -0
- cymedia-0.1.0a1/tests/test_graph_gpu.py +30 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0a1
|
|
4
|
+
|
|
5
|
+
First alpha.
|
|
6
|
+
|
|
7
|
+
- Graph engine: decode once, a filter chain and an encoder per branch, source group and object
|
|
8
|
+
numbers carried to every output, a keyframe at each group start.
|
|
9
|
+
- Realtime drop policy at group granularity, with input and branch events; frames wait while a
|
|
10
|
+
branch's encoder first opens.
|
|
11
|
+
- C sink ABI, a queue sink for Python, and native sinks passed as capsules.
|
|
12
|
+
- ABR ladder profiles for NVENC and software, and a live delay bench.
|
cymedia-0.1.0a1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Giovanni Marzot
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
cymedia-0.1.0a1/PKG-INFO
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cymedia
|
|
3
|
+
Version: 0.1.0a1
|
|
4
|
+
Summary: Low-latency, group-aligned media processing graphs on FFmpeg's libraries
|
|
5
|
+
Author: Giovanni Marzot
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/gmarzot/cymedia
|
|
8
|
+
Project-URL: Repository, https://github.com/gmarzot/cymedia
|
|
9
|
+
Project-URL: Issues, https://github.com/gmarzot/cymedia/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/gmarzot/cymedia/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: ffmpeg,video,transcoding,abr,nvenc,low-latency,moq
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: MacOS
|
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
+
Classifier: Programming Language :: C
|
|
17
|
+
Classifier: Programming Language :: Cython
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Multimedia :: Video :: Conversion
|
|
22
|
+
Requires-Python: >=3.12
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Provides-Extra: test
|
|
26
|
+
Requires-Dist: pytest>=8; extra == "test"
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# cymedia
|
|
30
|
+
|
|
31
|
+
Low-latency, group-aligned media processing graphs on FFmpeg's libraries, for Python.
|
|
32
|
+
|
|
33
|
+
A graph decodes a source once and feeds any number of branches. Each branch is a libavfilter
|
|
34
|
+
chain ending in an encoder, and its output goes to a sink. Source group numbers, object numbers
|
|
35
|
+
and timestamps pass through unchanged, and every branch starts a keyframe at each source group
|
|
36
|
+
start, so equally numbered groups line up across all outputs. The first graph is an ABR ladder.
|
|
37
|
+
|
|
38
|
+
**Status: alpha.** The NVIDIA path (NVDEC, `scale_cuda`, NVENC) and a software path (libopenh264,
|
|
39
|
+
else libx264) work, on Linux and macOS with Python 3.12 and 3.13. The API can change before 1.0.
|
|
40
|
+
|
|
41
|
+
## Install
|
|
42
|
+
|
|
43
|
+
cymedia builds against the system's FFmpeg, 6.1 or later. It needs FFmpeg's development files,
|
|
44
|
+
`pkg-config` and a C compiler:
|
|
45
|
+
|
|
46
|
+
sudo apt-get install pkg-config libavcodec-dev libavfilter-dev libavutil-dev # Ubuntu 24.04
|
|
47
|
+
brew install ffmpeg pkg-config # macOS
|
|
48
|
+
pip install cymedia
|
|
49
|
+
|
|
50
|
+
Prebuilt wheels with an LGPL FFmpeg are planned.
|
|
51
|
+
|
|
52
|
+
## Example
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from cymedia import Rung, ladder
|
|
56
|
+
|
|
57
|
+
rungs = [Rung(1280, 720, 3_750_000), Rung(640, 360, 900_000)]
|
|
58
|
+
with ladder(rungs, profile="nvenc", fps=(60, 1)) as g:
|
|
59
|
+
g.push(frame, group, obj, pts_us, key) # one H.264 access unit
|
|
60
|
+
for out in g.read(timeout=0.1):
|
|
61
|
+
... # out.branch, out.group, out.object, out.pts_us, out.key, out.group_start, out.data
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
- **Input** is one H.264 access unit per `push()`: Annex B, or 4-byte length prefixes with the
|
|
65
|
+
avcC passed as `extradata=`. `key` marks a group's first frame. `push()` returns False when
|
|
66
|
+
the frame was dropped.
|
|
67
|
+
- **Output** is Annex B, one `Output` per encoded frame, carrying its source frame's group,
|
|
68
|
+
object and timestamp. `g.fileno()` is readable while outputs are queued, for an event loop:
|
|
69
|
+
`loop.add_reader(g.fileno(), lambda: handle(g.read(0)))`.
|
|
70
|
+
- **`flush(timeout)`** ends input and waits for every branch's last frame; `stats()` and
|
|
71
|
+
`delays(branch)` report counters and recent push-to-output delays.
|
|
72
|
+
|
|
73
|
+
### Profiles
|
|
74
|
+
|
|
75
|
+
| Profile | Decode | Scale | Encode |
|
|
76
|
+
|---|---|---|---|
|
|
77
|
+
| `nvenc` | NVDEC | `scale_cuda` | `h264_nvenc`: p1, ultra low latency, CBR, no B-frames; filler NAL units stripped |
|
|
78
|
+
| `cpu` | software | `scale` | libopenh264, else libx264 (veryfast, zerolatency) |
|
|
79
|
+
|
|
80
|
+
Any other graph is a list of branches:
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from cymedia import Branch, Graph
|
|
84
|
+
|
|
85
|
+
g = Graph([Branch("scale=640:360,format=yuv420p", "libx264", {"preset": "veryfast"})],
|
|
86
|
+
decoder="h264", fps=(30, 1))
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## How it runs
|
|
90
|
+
|
|
91
|
+
- One decode thread decodes each source frame once, then runs every branch's filter chain.
|
|
92
|
+
- Each branch encodes on its own thread. Python's GIL is released throughout.
|
|
93
|
+
- In realtime mode (the default) a full queue drops instead of blocking. Input resumes at the next
|
|
94
|
+
group start; a branch that falls behind abandons the rest of that group, so a group is cut
|
|
95
|
+
short and never has a hole in it. While a branch's encoder first opens, frames wait rather
|
|
96
|
+
than drop. With `realtime=False`, queues block instead.
|
|
97
|
+
- Outputs go to a sink with a C ABI ([`cymedia_sink.h`](https://github.com/gmarzot/cymedia/blob/main/src/cymedia/cymedia_sink.h)). The
|
|
98
|
+
default sink queues them for `Graph.read()`; a native consumer passes its own sink as a
|
|
99
|
+
`cymedia.sink` capsule and keeps frames out of Python entirely.
|
|
100
|
+
|
|
101
|
+
## Measured delay
|
|
102
|
+
|
|
103
|
+
An RTX 4070, a 2160p60 H.264 source to six NVENC rungs (1440p to 180p), from `push()` to the
|
|
104
|
+
encoded output, the 4K decode included (about 4.4 ms of it):
|
|
105
|
+
|
|
106
|
+
| Run | GPU power state | p50 | p99 |
|
|
107
|
+
|---|---|---|---|
|
|
108
|
+
| 60 fps | P2, then P3 | 8.5–9.3 ms | 14.6–15.3 ms |
|
|
109
|
+
| 60 fps, clocks held up | P2 | 7.4–8.0 ms | 15.5–17.1 ms |
|
|
110
|
+
| 30 fps | P5 | 14.7–16.1 ms | 29.7–30.7 ms |
|
|
111
|
+
| 30 fps, clocks held up | P2/P3 | 8.5–9.0 ms | 16.0–16.9 ms |
|
|
112
|
+
|
|
113
|
+
Under a light load a GeForce card drops to a low power state and the delay doubles; no frames are
|
|
114
|
+
held. [`bench/ladder_delay.py`](https://github.com/gmarzot/cymedia/blob/main/bench/ladder_delay.py) measures it on your hardware.
|
|
115
|
+
|
|
116
|
+
## Used by
|
|
117
|
+
|
|
118
|
+
[aiomoqt](https://github.com/gmarzot/aiomoqt)'s `abr_ingest` sits in front of a MoQ relay and
|
|
119
|
+
publishes a broadcast plus a cymedia ladder under one catalog.
|
|
120
|
+
|
|
121
|
+
## Develop
|
|
122
|
+
|
|
123
|
+
python -m venv .venv && .venv/bin/pip install "Cython>=3.0.10" "setuptools>=77" pytest
|
|
124
|
+
.venv/bin/pip install --no-build-isolation -e .
|
|
125
|
+
.venv/bin/python -m pytest -q
|
|
126
|
+
|
|
127
|
+
GPU tests skip unless CUDA, `h264_nvenc` and `scale_cuda` are available. The delay bench:
|
|
128
|
+
|
|
129
|
+
.venv/bin/python bench/ladder_delay.py clip.mkv --profile nvenc --seconds 90
|
|
130
|
+
|
|
131
|
+
Contributor rules are in [AGENTS.md](https://github.com/gmarzot/cymedia/blob/main/AGENTS.md).
|
|
132
|
+
|
|
133
|
+
## License
|
|
134
|
+
|
|
135
|
+
MIT. cymedia links FFmpeg dynamically. A build for distribution must link an LGPL-only FFmpeg
|
|
136
|
+
(no `--enable-gpl`, no `--enable-nonfree`; `scale_cuda` built with `--enable-cuda-llvm`) and
|
|
137
|
+
publish that FFmpeg's source and configure line. Distribution packages often ship GPL builds,
|
|
138
|
+
which are fine for development but not for redistributed wheels. `cymedia.ffmpeg_info()` reports
|
|
139
|
+
the license of the FFmpeg in use.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# cymedia
|
|
2
|
+
|
|
3
|
+
Low-latency, group-aligned media processing graphs on FFmpeg's libraries, for Python.
|
|
4
|
+
|
|
5
|
+
A graph decodes a source once and feeds any number of branches. Each branch is a libavfilter
|
|
6
|
+
chain ending in an encoder, and its output goes to a sink. Source group numbers, object numbers
|
|
7
|
+
and timestamps pass through unchanged, and every branch starts a keyframe at each source group
|
|
8
|
+
start, so equally numbered groups line up across all outputs. The first graph is an ABR ladder.
|
|
9
|
+
|
|
10
|
+
**Status: alpha.** The NVIDIA path (NVDEC, `scale_cuda`, NVENC) and a software path (libopenh264,
|
|
11
|
+
else libx264) work, on Linux and macOS with Python 3.12 and 3.13. The API can change before 1.0.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
cymedia builds against the system's FFmpeg, 6.1 or later. It needs FFmpeg's development files,
|
|
16
|
+
`pkg-config` and a C compiler:
|
|
17
|
+
|
|
18
|
+
sudo apt-get install pkg-config libavcodec-dev libavfilter-dev libavutil-dev # Ubuntu 24.04
|
|
19
|
+
brew install ffmpeg pkg-config # macOS
|
|
20
|
+
pip install cymedia
|
|
21
|
+
|
|
22
|
+
Prebuilt wheels with an LGPL FFmpeg are planned.
|
|
23
|
+
|
|
24
|
+
## Example
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from cymedia import Rung, ladder
|
|
28
|
+
|
|
29
|
+
rungs = [Rung(1280, 720, 3_750_000), Rung(640, 360, 900_000)]
|
|
30
|
+
with ladder(rungs, profile="nvenc", fps=(60, 1)) as g:
|
|
31
|
+
g.push(frame, group, obj, pts_us, key) # one H.264 access unit
|
|
32
|
+
for out in g.read(timeout=0.1):
|
|
33
|
+
... # out.branch, out.group, out.object, out.pts_us, out.key, out.group_start, out.data
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
- **Input** is one H.264 access unit per `push()`: Annex B, or 4-byte length prefixes with the
|
|
37
|
+
avcC passed as `extradata=`. `key` marks a group's first frame. `push()` returns False when
|
|
38
|
+
the frame was dropped.
|
|
39
|
+
- **Output** is Annex B, one `Output` per encoded frame, carrying its source frame's group,
|
|
40
|
+
object and timestamp. `g.fileno()` is readable while outputs are queued, for an event loop:
|
|
41
|
+
`loop.add_reader(g.fileno(), lambda: handle(g.read(0)))`.
|
|
42
|
+
- **`flush(timeout)`** ends input and waits for every branch's last frame; `stats()` and
|
|
43
|
+
`delays(branch)` report counters and recent push-to-output delays.
|
|
44
|
+
|
|
45
|
+
### Profiles
|
|
46
|
+
|
|
47
|
+
| Profile | Decode | Scale | Encode |
|
|
48
|
+
|---|---|---|---|
|
|
49
|
+
| `nvenc` | NVDEC | `scale_cuda` | `h264_nvenc`: p1, ultra low latency, CBR, no B-frames; filler NAL units stripped |
|
|
50
|
+
| `cpu` | software | `scale` | libopenh264, else libx264 (veryfast, zerolatency) |
|
|
51
|
+
|
|
52
|
+
Any other graph is a list of branches:
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from cymedia import Branch, Graph
|
|
56
|
+
|
|
57
|
+
g = Graph([Branch("scale=640:360,format=yuv420p", "libx264", {"preset": "veryfast"})],
|
|
58
|
+
decoder="h264", fps=(30, 1))
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## How it runs
|
|
62
|
+
|
|
63
|
+
- One decode thread decodes each source frame once, then runs every branch's filter chain.
|
|
64
|
+
- Each branch encodes on its own thread. Python's GIL is released throughout.
|
|
65
|
+
- In realtime mode (the default) a full queue drops instead of blocking. Input resumes at the next
|
|
66
|
+
group start; a branch that falls behind abandons the rest of that group, so a group is cut
|
|
67
|
+
short and never has a hole in it. While a branch's encoder first opens, frames wait rather
|
|
68
|
+
than drop. With `realtime=False`, queues block instead.
|
|
69
|
+
- Outputs go to a sink with a C ABI ([`cymedia_sink.h`](https://github.com/gmarzot/cymedia/blob/main/src/cymedia/cymedia_sink.h)). The
|
|
70
|
+
default sink queues them for `Graph.read()`; a native consumer passes its own sink as a
|
|
71
|
+
`cymedia.sink` capsule and keeps frames out of Python entirely.
|
|
72
|
+
|
|
73
|
+
## Measured delay
|
|
74
|
+
|
|
75
|
+
An RTX 4070, a 2160p60 H.264 source to six NVENC rungs (1440p to 180p), from `push()` to the
|
|
76
|
+
encoded output, the 4K decode included (about 4.4 ms of it):
|
|
77
|
+
|
|
78
|
+
| Run | GPU power state | p50 | p99 |
|
|
79
|
+
|---|---|---|---|
|
|
80
|
+
| 60 fps | P2, then P3 | 8.5–9.3 ms | 14.6–15.3 ms |
|
|
81
|
+
| 60 fps, clocks held up | P2 | 7.4–8.0 ms | 15.5–17.1 ms |
|
|
82
|
+
| 30 fps | P5 | 14.7–16.1 ms | 29.7–30.7 ms |
|
|
83
|
+
| 30 fps, clocks held up | P2/P3 | 8.5–9.0 ms | 16.0–16.9 ms |
|
|
84
|
+
|
|
85
|
+
Under a light load a GeForce card drops to a low power state and the delay doubles; no frames are
|
|
86
|
+
held. [`bench/ladder_delay.py`](https://github.com/gmarzot/cymedia/blob/main/bench/ladder_delay.py) measures it on your hardware.
|
|
87
|
+
|
|
88
|
+
## Used by
|
|
89
|
+
|
|
90
|
+
[aiomoqt](https://github.com/gmarzot/aiomoqt)'s `abr_ingest` sits in front of a MoQ relay and
|
|
91
|
+
publishes a broadcast plus a cymedia ladder under one catalog.
|
|
92
|
+
|
|
93
|
+
## Develop
|
|
94
|
+
|
|
95
|
+
python -m venv .venv && .venv/bin/pip install "Cython>=3.0.10" "setuptools>=77" pytest
|
|
96
|
+
.venv/bin/pip install --no-build-isolation -e .
|
|
97
|
+
.venv/bin/python -m pytest -q
|
|
98
|
+
|
|
99
|
+
GPU tests skip unless CUDA, `h264_nvenc` and `scale_cuda` are available. The delay bench:
|
|
100
|
+
|
|
101
|
+
.venv/bin/python bench/ladder_delay.py clip.mkv --profile nvenc --seconds 90
|
|
102
|
+
|
|
103
|
+
Contributor rules are in [AGENTS.md](https://github.com/gmarzot/cymedia/blob/main/AGENTS.md).
|
|
104
|
+
|
|
105
|
+
## License
|
|
106
|
+
|
|
107
|
+
MIT. cymedia links FFmpeg dynamically. A build for distribution must link an LGPL-only FFmpeg
|
|
108
|
+
(no `--enable-gpl`, no `--enable-nonfree`; `scale_cuda` built with `--enable-cuda-llvm`) and
|
|
109
|
+
publish that FFmpeg's source and configure line. Distribution packages often ship GPL builds,
|
|
110
|
+
which are fine for development but not for redistributed wheels. `cymedia.ffmpeg_info()` reports
|
|
111
|
+
the license of the FFmpeg in use.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77", "Cython>=3.0.10"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "cymedia"
|
|
7
|
+
version = "0.1.0a1"
|
|
8
|
+
description = "Low-latency, group-aligned media processing graphs on FFmpeg's libraries"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "Giovanni Marzot" }]
|
|
14
|
+
keywords = ["ffmpeg", "video", "transcoding", "abr", "nvenc", "low-latency", "moq"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"Operating System :: MacOS",
|
|
19
|
+
"Operating System :: POSIX :: Linux",
|
|
20
|
+
"Programming Language :: C",
|
|
21
|
+
"Programming Language :: Cython",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Programming Language :: Python :: 3.13",
|
|
25
|
+
"Topic :: Multimedia :: Video :: Conversion",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
Homepage = "https://github.com/gmarzot/cymedia"
|
|
30
|
+
Repository = "https://github.com/gmarzot/cymedia"
|
|
31
|
+
Issues = "https://github.com/gmarzot/cymedia/issues"
|
|
32
|
+
Changelog = "https://github.com/gmarzot/cymedia/blob/main/CHANGELOG.md"
|
|
33
|
+
|
|
34
|
+
[project.optional-dependencies]
|
|
35
|
+
test = ["pytest>=8"]
|
|
36
|
+
|
|
37
|
+
[tool.setuptools]
|
|
38
|
+
package-dir = { "" = "src" }
|
|
39
|
+
packages = ["cymedia"]
|
|
40
|
+
|
|
41
|
+
[tool.setuptools.package-data]
|
|
42
|
+
cymedia = ["*.h"]
|
|
43
|
+
|
|
44
|
+
[tool.pytest.ini_options]
|
|
45
|
+
testpaths = ["tests"]
|
|
46
|
+
|
|
47
|
+
[tool.ruff]
|
|
48
|
+
line-length = 100
|
|
49
|
+
|
|
50
|
+
[tool.ruff.lint]
|
|
51
|
+
select = ["E", "F", "W"]
|
cymedia-0.1.0a1/setup.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
|
|
3
|
+
from Cython.Build import cythonize
|
|
4
|
+
from setuptools import Extension, setup
|
|
5
|
+
|
|
6
|
+
LIBS = ["libavcodec", "libavfilter", "libavutil"]
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def pkg_config(flag):
|
|
10
|
+
return subprocess.check_output(["pkg-config", flag, *LIBS], text=True).split()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
ext = Extension(
|
|
14
|
+
"cymedia._core",
|
|
15
|
+
sources=["src/cymedia/_core.pyx", "src/cymedia/engine.c", "src/cymedia/qsink.c"],
|
|
16
|
+
include_dirs=["src/cymedia"],
|
|
17
|
+
extra_compile_args=pkg_config("--cflags") + ["-std=c11", "-O2", "-Wall"],
|
|
18
|
+
extra_link_args=pkg_config("--libs") + ["-lpthread"],
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
setup(ext_modules=cythonize([ext], compiler_directives={"language_level": 3}))
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Low-latency, group-aligned media processing graphs on FFmpeg's libraries."""
|
|
2
|
+
from cymedia._core import (Graph, ffmpeg_info, have_decoder, have_encoder, have_filter,
|
|
3
|
+
hw_available, set_ffmpeg_log_level)
|
|
4
|
+
from cymedia._types import Branch, Output
|
|
5
|
+
from cymedia.ladder import PROFILES, Rung, ladder
|
|
6
|
+
|
|
7
|
+
__all__ = ["Branch", "Graph", "Output", "PROFILES", "Rung", "ffmpeg_info", "have_decoder",
|
|
8
|
+
"have_encoder", "have_filter", "hw_available", "ladder", "set_ffmpeg_log_level"]
|