Skip to content

Commit 021ab91

Browse files
committed
[build] Enable NVIDIA Video Codec SDK support for hardware video decode/encode
Add NVCUVID and NVCUVENC support using the Video Codec SDK from the deps repository. This enables hardware-accelerated video decoding and encoding via NVIDIA GPUs.
1 parent 8e736ff commit 021ab91

3 files changed

Lines changed: 157 additions & 2 deletions

File tree

.github/workflows/build_wheels_windows.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ jobs:
4949
cuda-path-version: 'v12.9'
5050
cudnn-archive: 'cudnn-windows-x86_64-9.18.1.3_cuda12-archive.zip'
5151
cudnn-folder: 'cudnn-windows-x86_64-9.18.1.3_cuda12-archive'
52+
video-codec-sdk-archive: 'Video_Codec_SDK_13.0.37.zip'
53+
video-codec-sdk-folder: 'Video_Codec_SDK_13.0.37'
5254
cuda-arch-bin: '5.0;5.2;6.0;6.1;7.0;7.5;8.0;8.6;8.9;9.0;10.0'
5355
cuda-arch-ptx: '10.0'
5456
cache-key: 'nvidia-deps-cuda-12.9.1-cudnn-9.18.1.3'
@@ -60,6 +62,8 @@ jobs:
6062
# cuda-path-version: 'v13.1'
6163
# cudnn-archive: 'cudnn-windows-x86_64-9.18.1.3_cuda13-archive.zip'
6264
# cudnn-folder: 'cudnn-windows-x86_64-9.18.1.3_cuda13-archive'
65+
# video-codec-sdk-archive: 'Video_Codec_SDK_13.0.37.zip'
66+
# video-codec-sdk-folder: 'Video_Codec_SDK_13.0.37'
6367
# cuda-arch-bin: '7.5;8.0;8.6;8.9;9.0;10.0;12.0'
6468
# cuda-arch-ptx: '12.0'
6569
# cache-key: 'nvidia-deps-cuda-13.1.1-cudnn-9.18.1.3'
@@ -135,6 +139,19 @@ jobs:
135139
echo "CUDNN_INCLUDE_DIR=$CUDNN_PATH/include" | Out-File -FilePath $env:GITHUB_ENV -Append
136140
Copy-Item -Path "$CUDNN_PATH/bin/*" -Destination . -Include "*.dll"
137141
shell: pwsh
142+
- name: 🔧 Install NVIDIA Video Codec SDK
143+
run: |
144+
$sdk_path = ".deps/Nvidia/${{ matrix.video-codec-sdk-archive }}"
145+
if (-not (Test-Path $sdk_path)) {
146+
throw "Video Codec SDK archive not found at $sdk_path"
147+
}
148+
echo "Installing Video Codec SDK..."
149+
7z x $sdk_path
150+
$SDK_PATH = "D:/a/opencv-python-cuda/opencv-python-cuda/${{ matrix.video-codec-sdk-folder }}"
151+
echo "CUDA_nvcuvid_LIBRARY=$SDK_PATH/Lib/win/x64/nvcuvid.lib" | Out-File -FilePath $env:GITHUB_ENV -Append
152+
echo "CUDA_nvencodeapi_LIBRARY=$SDK_PATH/Lib/win/x64/nvencodeapi.lib" | Out-File -FilePath $env:GITHUB_ENV -Append
153+
echo "NVCUVID_INCLUDE_DIR=$SDK_PATH/Interface" | Out-File -FilePath $env:GITHUB_ENV -Append
154+
shell: pwsh
138155

139156
- name: Restore build artifacts
140157
uses: actions/cache/restore@v3

WORKFLOW.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# Workflow Guide
2+
3+
## Repository Setup
4+
5+
### Cloning the Repository
6+
7+
```bash
8+
git clone https://github.com/Breakthrough/opencv-python-cuda.git
9+
cd opencv-python-cuda
10+
```
11+
12+
### Adding Upstream Remote
13+
14+
To sync with the main `opencv/opencv-python` repository, add it as a remote:
15+
16+
```bash
17+
git remote add upstream https://github.com/opencv/opencv-python.git
18+
```
19+
20+
### Preventing Tag Pollution
21+
22+
The upstream `opencv/opencv-python` repo has numeric tags (0, 1, 2, ... 90) that will pollute your local repo during fetches. To prevent this, configure the remote to exclude tags:
23+
24+
```bash
25+
git config remote.upstream.tagOpt --no-tags
26+
git config --add remote.upstream.fetch '^refs/tags/*'
27+
```
28+
29+
The `tagOpt` setting alone is sometimes not respected, so the negative refspec (`^refs/tags/*`) explicitly excludes all tags.
30+
31+
### Syncing with Upstream
32+
33+
After configuring the remote, you can sync without getting unwanted tags:
34+
35+
```bash
36+
git fetch upstream
37+
git pull --rebase upstream 4.x
38+
```
39+
40+
### Removing Accidentally Fetched Tags
41+
42+
If you already fetched the numeric tags, remove them with:
43+
44+
```bash
45+
git tag -d 0 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 68 70 72 74 76 78 80 82 84 86 88 90
46+
```
47+
48+
---
49+
50+
## Triggering Builds
51+
52+
To trigger the Windows CUDA build workflow:
53+
54+
```bash
55+
gh workflow run build_wheels_windows.yml --ref 4.x-cuda -R Breakthrough/opencv-python-cuda
56+
```
57+
58+
**Important:** Always specify `-R Breakthrough/opencv-python-cuda` when using `gh` commands. This repo is a fork of `opencv/opencv-python`, and `gh` will default to the parent repository without the explicit `-R` flag.
59+
60+
### Build Options
61+
62+
| Option | Description | Default |
63+
|--------|-------------|---------|
64+
| `restore_build_cache` | Restore build cache from previous runs | `true` |
65+
| `save_build_cache` | Save build cache after completion | `true` |
66+
| `rolling_build` | Use latest commit from upstream OpenCV | `false` |
67+
68+
Example with options:
69+
70+
```bash
71+
gh workflow run build_wheels_windows.yml --ref 4.x-cuda -R Breakthrough/opencv-python-cuda \
72+
-f restore_build_cache=false \
73+
-f save_build_cache=true
74+
```
75+
76+
### Force Rebuild (No Cache)
77+
78+
To force a complete rebuild without using cached artifacts:
79+
80+
```bash
81+
gh workflow run build_wheels_windows.yml --ref 4.x-cuda -R Breakthrough/opencv-python-cuda \
82+
-f restore_build_cache=false
83+
```
84+
85+
---
86+
87+
## Monitoring Builds
88+
89+
List recent runs:
90+
91+
```bash
92+
gh run list -R Breakthrough/opencv-python-cuda --limit 5
93+
```
94+
95+
Watch a running build:
96+
97+
```bash
98+
gh run watch <run-id> -R Breakthrough/opencv-python-cuda
99+
```
100+
101+
View build details:
102+
103+
```bash
104+
gh run view <run-id> -R Breakthrough/opencv-python-cuda
105+
```
106+
107+
---
108+
109+
## Reference: Git Config for Remotes
110+
111+
After setup, your `.git/config` remote sections should look like:
112+
113+
```ini
114+
[remote "origin"]
115+
url = https://github.com/Breakthrough/opencv-python-cuda.git
116+
fetch = +refs/heads/*:refs/remotes/origin/*
117+
118+
[remote "upstream"]
119+
url = https://github.com/opencv/opencv-python.git
120+
fetch = +refs/heads/*:refs/remotes/upstream/*
121+
fetch = ^refs/tags/*
122+
tagOpt = --no-tags
123+
```

setup.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,11 @@ def main():
162162
cudnn_library = os.environ["CUDNN_LIBRARY"]
163163
cudnn_include_dir = os.environ["CUDNN_INCLUDE_DIR"]
164164

165+
# Video Codec SDK paths for NVCUVID/NVCUVENC (optional, enables hardware video decode/encode)
166+
nvcuvid_library = os.environ.get("CUDA_nvcuvid_LIBRARY", "")
167+
nvencodeapi_library = os.environ.get("CUDA_nvencodeapi_LIBRARY", "")
168+
nvcuvid_include_dir = os.environ.get("NVCUVID_INCLUDE_DIR", "")
169+
165170
cmake_args = (
166171
(ci_cmake_generator if is_CI_build else [])
167172
+ [
@@ -191,13 +196,23 @@ def main():
191196
"-DPYTHON3_LIMITED_API=ON",
192197
"-DBUILD_OPENEXR=ON",
193198
"-DWITH_CUDA=ON",
194-
# TODO(@Breakthrough): Download and install the required dependencies to enable this in build_wheels_windows.yml.
195-
"-DWITH_NVCUVID=OFF",
199+
"-DWITH_NVCUVID=ON",
200+
"-DWITH_NVCUVENC=ON",
196201
f"-DCUDA_ARCH_BIN={cuda_arch_bin}",
197202
f"-DCUDA_ARCH_PTX={cuda_arch_ptx}",
198203
f"-DCUDNN_LIBRARY={cudnn_library}",
199204
f"-DCUDNN_INCLUDE_DIR={cudnn_include_dir}",
200205
]
206+
+ (
207+
# Video Codec SDK paths for hardware video decode/encode support
208+
[
209+
f"-DCUDA_nvcuvid_LIBRARY={nvcuvid_library}",
210+
f"-DCUDA_nvencodeapi_LIBRARY={nvencodeapi_library}",
211+
f"-DCMAKE_INCLUDE_PATH={nvcuvid_include_dir}",
212+
]
213+
if nvcuvid_library and nvcuvid_include_dir
214+
else []
215+
)
201216
+ (
202217
# CUDA 12.9+ requires MSVC's conformant preprocessor for CCCL headers.
203218
# -Xcompiler passes the flag from nvcc to the host compiler (MSVC).

0 commit comments

Comments
 (0)