3个不稳定版本
0.2.0 | 2024年6月23日 |
---|---|
0.1.2 |
|
0.1.1 | 2023年2月25日 |
0.1.0 | 2023年2月13日 |
#109 in 音频
1.5MB
47K SLoC
unsafe-libopus
这个库是将libopus 1.3.1从C语言翻译为不安全Rust语言,并使用c2rust辅助完成的。
因为它与C代码的结构几乎相同,并且充满了“不安全”的元素,所以被称为“不安全”的libopus。
这种转换仍然允许你在纯Rust环境中使用库,无需链接器技巧和动态链接问题,从而摆脱C编译器工具链。
这也许可以是libopus的更符合Rust风格的实现的开端,尽管我不确定这是否值得付出努力。
使用方法
您可以通过使用来自此PR的opus
crate的分支来利用此库
[dependencies]
opus = { git = "https://github.com/DCNick3/opus-rs.git", branch = "unsafe-libopus", default-features = false, features = ["unsafe-libopus-backend"] }
也许,这个库将来会有安全的API,但现在,它主要是audiopus_sys
crate的替代品。
转换技术
首先,使用以下命令编译了libopus 1.3.1:
CC=clang ./configure --disable-shared --disable-stack-protector --enable-extra-programs --disable-doc --disable-asm --disable-rtcd --disable-intrinsics --disable-dependency-tracking--disable-maintainer-mode --enable-hardening
CC=clang compiledb make -j
然后,使用生成的compile_commands.json
文件,使用以下命令将C代码转换为Rust:
c2rust transpile compile_commands.json -o . --overwrite-existing --reorganize-definitions --emit-modules --translate-const-macros --emit-build-files
然后,手动重新组织生成的代码,以删除所有结构体的重复,并消除对#[no_mangle] extern "C"
函数的使用:它们现在都链接到Rust,无需导出。
其他重构包括
- 将测试二进制文件从库中分离出来作为“示例”
- 通过在库中定义它们的变体来删除对libc函数的依赖(灵感来自unsafe-libyaml)
- 通过将libc类型替换为具体的Rust类型来删除对libc crate的依赖(例如
libc::c_int
->i32
等) - 通过将 C 的变长参数替换为自定义的 VarArgs 结构体来移除 C 的变长参数,因为 Rust 中的 C 变长参数还不稳定。这使得
opus_*_ctl
函数族变为宏。
性能
该库的翻译未使用内联汇编、处理器 intrinsic 和运行时 CPU 检测,因此目前不如原始代码快。具有这些功能的 C 版本在我的机器上比 Rust 版本快约 20%。
正确性
该库使用 C 代码库中的(大部分)原始测试进行测试。它们以 Rust 集成测试的形式存在于 tests
目录中。C 代码库中的许多单元测试尚未翻译。
测试的核心在于 unsafe-libopus-tools/src/bin/run_vectors2.rs
。它使用 IETF 发布的测试向量对解码器和编码器进行测试,并将结果与位于 upstream-libopus
的 opus 1.3.1 的 C 实现进行比较。它对结果进行了一些小的修改,以提高可移植性。
解码器通过解码测试向量和将结果与多个输出采样率下的 C 实现进行比较来测试。它们被检查以完全匹配。
对编码器执行同样的操作,在多个不同的比特率下运行,并将编码结果与 C 实现进行比较。除了比特率外,没有更改其他参数,这目前是测试的一个弱点。
严格来说,对于这是一个有效实现,不需要相同的编码结果:编码器可以自由做出很多选择,从而产生不同的质量结果。然而,制作一个比原始 opus 更好的编解码器不是目标。因此,通过要求完全相同的结果,我们防止了编码器行为的任何偏差。
安全性
目前,大多数代码都是不安全的,因为它是 C 代码的直接翻译。
我正在逐步重构代码,以确保其某些部分的安全性。以前保持有效性是一个挑战,但现在有了针对 C 代码实现进行测试的测试,这应该会更容易。
许可证
与原始 libopus 一样,unsafe-libopus
在 BSD 3 条款许可证下授权。