Skip to content

Commit 831ed9c

Browse files
committed
修复 Windows 构建与移植性问题
- CMakeLists: 移除硬编码的本机 PKG_CONFIG_PATH(M:/msys64),改由 PKG_CONFIG_PATH/CMAKE_PREFIX_PATH 提供;MinGW64 shell 下自动发现 - CMakeLists: Windows 下对 vlc_threads.h 的 vlc_poll() 隐式 poll 声明 降级为警告(GCC 14+ 默认报硬错误),该 inline 插件不会调用 - usm_vlc_video: 试 key 解密改用堆分配,去掉栈上 VLA(帧大小来自文件, 超大帧会爆栈) - usm_keys: Windows 默认 key 文件路径改用 %APPDATA%\\vlc(官网版 VLC 配置位置) - dll_entry.c: 补末尾换行 - README: 重写为 Linux/MSYS2 双平台说明,修正密钥路径,恢复构建/测试节
1 parent 0ee1e56 commit 831ed9c

5 files changed

Lines changed: 102 additions & 33 deletions

File tree

CMakeLists.txt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ project(vlc_plugin_usm C)
44
set(CMAKE_C_STANDARD 11)
55
set(CMAKE_C_STANDARD_REQUIRED ON)
66
set(CMAKE_C_EXTENSIONS OFF)
7-
set(ENV{PKG_CONFIG_PATH} "M:/msys64/mingw64/lib/pkgconfig")
87

8+
# 从 MSYS2 MinGW64 shell 构建时 pkg-config 会自动找到 vlc-plugin/vpx。
9+
# 若在其它环境构建,通过环境变量 PKG_CONFIG_PATH 或 -DCMAKE_PREFIX_PATH 指定,
10+
# 不要在此处硬编码本机路径。
911
find_package(PkgConfig REQUIRED)
1012
pkg_check_modules(VLC_PLUGIN REQUIRED vlc-plugin)
1113
pkg_check_modules(VPX REQUIRED vpx)
@@ -23,6 +25,10 @@ target_compile_options(usm_core PRIVATE -Wall -Wextra -Wpedantic)
2325

2426
if(WIN32)
2527
list(APPEND PLUGIN_SOURCES src/dll_entry.c)
28+
# VLC 的 vlc_threads.h 在 Windows 分支里有个 static inline vlc_poll(),它调用 POSIX
29+
# poll(),而 mingw 只有 WSAPoll。该 inline 本插件不会调用(不会产生链接引用),但
30+
# GCC 14+ 默认把“隐式声明 poll”当硬错误,导致仅含 VLC 头就编不过。降级为警告即可。
31+
set(PLUGIN_WIN_C_FLAGS -Wno-error=implicit-function-declaration)
2632
endif()
2733

2834
add_library(usm_plugin MODULE
@@ -38,7 +44,7 @@ set_target_properties(usm_plugin PROPERTIES
3844
)
3945
target_include_directories(usm_plugin PRIVATE ${VLC_PLUGIN_INCLUDE_DIRS} src)
4046
target_include_directories(usm_plugin PRIVATE ${VPX_INCLUDE_DIRS})
41-
target_compile_options(usm_plugin PRIVATE ${VLC_PLUGIN_CFLAGS_OTHER} -Wall -Wextra)
47+
target_compile_options(usm_plugin PRIVATE ${VLC_PLUGIN_CFLAGS_OTHER} -Wall -Wextra ${PLUGIN_WIN_C_FLAGS})
4248
target_link_libraries(usm_plugin PRIVATE usm_core ${VLC_PLUGIN_LIBRARIES} ${VPX_LIBRARIES})
4349
target_link_directories(usm_plugin PRIVATE ${VLC_PLUGIN_LIBRARY_DIRS} ${VPX_LIBRARY_DIRS})
4450
target_compile_definitions(usm_plugin PRIVATE _GNU_SOURCE MODULE_STRING="usm")

README.md

Lines changed: 71 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,59 +11,107 @@ VP9 解码器播放。
1111
- 从默认 key 文件读取密钥,适合在文件管理器里双击打开。
1212
- 基于时间轴拖动进度。
1313

14-
## 安装
14+
## 构建
15+
16+
### Linux
17+
18+
```sh
19+
cmake -S . -B build
20+
cmake --build build
21+
ctest --test-dir build --output-on-failure
22+
```
23+
24+
### Windows (MSYS2 / MinGW64)
25+
26+
在 MSYS2 的 **MINGW64** shell 里安装依赖并构建:
1527

16-
构建完成后将libusm_plugin.dll放入以下路径:
28+
```sh
29+
pacman -S --needed mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake \
30+
mingw-w64-x86_64-pkgconf mingw-w64-x86_64-ninja \
31+
mingw-w64-x86_64-libvpx mingw-w64-x86_64-vlc
1732

33+
cmake -S . -B build -G Ninja
34+
cmake --build build
35+
ctest --test-dir build --output-on-failure
1836
```
19-
# VLC Windows版默认安装路径:
20-
C:\Program Files\VideoLAN\VLC\plugins\demux(经测试暂不可用)
2137

22-
# MSYS2版VLC默认安装路径:
23-
C:\msys64\mingw64\lib\vlc\plugins\demux
38+
从 MINGW64 shell 构建时 `pkg-config` 会自动找到 `vlc-plugin``vpx`,无需手动配置
39+
路径。若在其它环境构建,用环境变量 `PKG_CONFIG_PATH``-DCMAKE_PREFIX_PATH` 指定。
40+
41+
## 安装
42+
43+
### Arch 包
44+
45+
```sh
46+
cd packaging/arch
47+
PKGDEST=../.. makepkg -f
48+
cd ../..
49+
sudo pacman -U vlc-plugin-usm-0.1.0-3-x86_64.pkg.tar.zst
2450
```
2551

26-
安装后若不识别请手动删除 `plugins.dat` 并使用
52+
安装后 VLC 的插件缓存会由 pacman hook 自动更新。
53+
54+
### Windows
55+
56+
把构建出的 `libusm_plugin.dll` 放进 VLC 的 `plugins/demux` 目录:
57+
58+
- MSYS2 版 VLC:`C:\msys64\mingw64\lib\vlc\plugins\demux\`
59+
- 官网版 VLC:`C:\Program Files\VideoLAN\VLC\plugins\demux\`
60+
61+
> 注意:本插件依赖 libvpx,MSYS2 构建出的 DLL 会动态链接 `libvpx-1.dll` 以及
62+
> mingw 运行时(`libgcc_s_seh-1.dll``libwinpthread-1.dll`)。MSYS2 版 VLC 因为
63+
> 这些 DLL 在 `mingw64\bin`(已在 PATH 上)能正常加载;官网版 VLC 不自带这些 DLL,
64+
> 直接拷过去会因找不到依赖而静默加载失败。让官网版可用的方案仍在完善中。
65+
66+
安装后若不识别,删除缓存 `plugins.dat` 并重建:
67+
2768
```powershell
28-
& "C:\Program Files\VideoLAN\VLC\vlc-cache-gen.exe" ./plugins
69+
& "C:\Program Files\VideoLAN\VLC\vlc-cache-gen.exe" "C:\Program Files\VideoLAN\VLC\plugins"
2970
```
30-
重建缓存。~~(貌似没用)~~
3171

3272
## 配置密钥
3373

34-
~~推荐把 key 写到默认配置文件里,这样双击文件打开时也能自动解密:~~
74+
推荐把 key 写到 VLC 配置目录下的默认文件里,这样双击文件打开时也能自动解密。
75+
76+
Linux:
3577

3678
```sh
3779
mkdir -p ~/.config/vlc
3880
printf '0x7F4551499DF55E68\n' > ~/.config/vlc/usm-keys.txt
3981
```
4082

41-
~~默认读取顺序:~~
83+
Windows(官网版 VLC):
84+
85+
```powershell
86+
New-Item -ItemType Directory -Force "$env:APPDATA\vlc" | Out-Null
87+
Set-Content "$env:APPDATA\vlc\usm-keys.txt" "0x7F4551499DF55E68"
88+
```
4289

43-
~~1. `$XDG_CONFIG_HOME/vlc/usm-keys.txt`~~
44-
~~2. `~/.config/vlc/usm-keys.txt`~~
90+
默认读取顺序:
4591

46-
~~key 文件支持十进制或 `0x` 前缀的十六进制;多个 key 可以用逗号、分号、
47-
空白或换行分隔。`#` 后面的内容会当作注释。~~
48-
(Windows下未经测试)
92+
- Windows:`%APPDATA%\vlc\usm-keys.txt`
93+
- Linux:`$XDG_CONFIG_HOME/vlc/usm-keys.txt`,否则 `~/.config/vlc/usm-keys.txt`
4994

95+
key 文件支持十进制或 `0x` 前缀的十六进制;多个 key 可以用逗号、分号、空白或换行
96+
分隔。`#` 后面的内容会当作注释。配置多个 key 时,插件会用 libvpx 试解码自动选出
97+
能正确解密的那个。
5098

5199
也可以启动时临时传 key:
52100

101+
```sh
102+
vlc --usm-keys 0x7F4551499DF55E68 /path/to/movie.dat
103+
```
104+
53105
```powershell
54-
& "\path\to\vlc\vlc.exe" --usm-keys 0x7F4551499DF55E68 \path\to\movie.dat
106+
& "C:\Program Files\VideoLAN\VLC\vlc.exe" --usm-keys 0x7F4551499DF55E68 C:\path\to\movie.dat
55107
```
56108

57109
或者指定一个自定义 key 文件:
58110

59-
```powershell
60-
& "\path\to\vlc\vlc.exe" --usm-key-file \path\to\usm-keys.txt \path\to\movie.dat
111+
```sh
112+
vlc --usm-key-file /path/to/usm-keys.txt /path/to/movie.dat
61113
```
62114

63-
## 构建
64-
~~我不知道,我用vscode cmake插件构建的~~
65-
构建前请先修改 `CMakeList' 中的 'set(ENV{PKG_CONFIG_PATH} "")` 为你自己的 `pkgconfig` 路径
66-
67115
## 已知限制
68116

69117
- 当前只输出视频流,没有输出音频流。

src/dll_entry.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ BOOL WINAPI DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved
1313
return TRUE;
1414
}
1515

16-
#endif
16+
#endif

src/usm_keys.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ char *usm_default_key_file_path_from_env(const char *xdg_config_home,
9090

9191
char *usm_default_key_file_path(void)
9292
{
93+
#ifdef _WIN32
94+
// 官网版 VLC 把用户配置放在 %APPDATA%\vlc\,优先使用
95+
const char *appdata = getenv("APPDATA");
96+
if (appdata != NULL && appdata[0] != '\0') {
97+
return join_key_file_path(appdata, "\\vlc\\usm-keys.txt");
98+
}
99+
#endif
93100
return usm_default_key_file_path_from_env(getenv("XDG_CONFIG_HOME"), getenv("HOME"));
94101
}
95102

src/usm_vlc_video.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <vpx/vpx_decoder.h>
66

77
#include <inttypes.h>
8+
#include <stdlib.h>
89
#include <string.h>
910

1011
static bool payload_needs_decrypt(size_t payload_size)
@@ -52,19 +53,26 @@ static bool decrypted_frame_decodes(demux_t *demux, size_t key_index,
5253
block_t *payload,
5354
const usm_decryption_keys_t *keys)
5455
{
55-
uint8_t trial[payload->i_buffer];
56+
// 用堆而非栈上 VLA:payload 大小来自文件,超大帧会爆栈
57+
uint8_t *trial = malloc(payload->i_buffer);
58+
if (trial == NULL) {
59+
return false;
60+
}
5661
memcpy(trial, payload->p_buffer, payload->i_buffer);
5762
usm_decrypt_video(trial, payload->i_buffer, keys);
5863

5964
const uint8_t *frame_data = NULL;
6065
size_t frame_size = 0;
6166
uint64_t timestamp = 0;
62-
if (!usm_ivf_parse_payload_frame(trial, payload->i_buffer, &frame_data,
63-
&frame_size, &timestamp)) {
64-
return false;
65-
}
66-
demux_sys_t *sys = demux->p_sys;
67-
return probe_decode_frame(&sys->key_probes[key_index], frame_data, frame_size);
67+
bool ok = false;
68+
if (usm_ivf_parse_payload_frame(trial, payload->i_buffer, &frame_data,
69+
&frame_size, &timestamp)) {
70+
demux_sys_t *sys = demux->p_sys;
71+
ok = probe_decode_frame(&sys->key_probes[key_index], frame_data,
72+
frame_size);
73+
}
74+
free(trial);
75+
return ok;
6876
}
6977

7078
static bool select_matching_key(demux_t *demux, block_t *payload)

0 commit comments

Comments
 (0)