c++ - 将 SSE 指令与 Libavcodec 一起使用
问题描述
我编写了一个简单的视频会议应用程序,它使用多个线程进行视频和音频混合。我使用 libavcodec (ffmpeg) 编解码器来混合视频。据我所知,libavcodec 使用 SSE 指令来实现高性能。对于音频混合,我使用了一个简单的混合算法,它只是添加了样本。我已经用 C++ 中的 sipmlefor
循环编写了加法算法,但现在我想使用这样的 SSE 指令对其进行优化:
__m128i* d = (__m128i*) pOutBuffer;
__m128i* s = (__m128i*) pInBuffer;
for (DWORD n = (DWORD)(nSizeToMix + 7) >> 3; n != 0; --n, ++d, ++s)
{
//Load data in SSE registers
__m128i xmm1 = _mm_load_si128(d);
__m128i xmm2 = _mm_load_si128(s);
//SSE2 sum
_mm_store_si128(d, _mm_add_epi16(xmm1, xmm2));
}
音频混合是与视频混合同时完成的一个单独的线程。当我使用 SSE 指令时,应用程序在与音频混合无关的位置突然崩溃,在视频的编码/解码中。
似乎因为 libavcodec 使用 SSE 寄存器和指令,我的代码与之冲突。有什么方法可以使用 SSE 指令而不会与 libvcodec (ffmpeg) 发生任何冲突?任何建议表示赞赏。
解决方案
只要您使用现代编译器(超过 10 年)并且您没有在汇编中编码,上下文切换就应该没问题。编译器知道其目标平台的 ABI,因此您不必知道。
如果您包含导致应用程序崩溃的确切代码,则最可能的原因是对齐问题。替换_mm_load_si128
为_mm_loadu_si128
, _mm_store_si128
with_mm_storeu_si128
并查看是否有帮助。
更新 1:另一个可能的原因是 SSE 版本完成速度太快,这会触发并发错误。尝试Sleep( 2 )
在循环之后添加例如调用,如果视频可以正常工作,则意味着您需要修复跨线程推送或拉取数据的代码。
更新 2:正如 Alan 指出的,数组(缓冲区)的大小可能不是 16 字节(16 * (nSizeToMix + 7) / 8
)的倍数。这肯定会导致您的应用程序崩溃或内存损坏。
推荐阅读
- python - 如何检测图像分类的过度拟合?
- android - 以编程方式将具有权重的视图添加到 Kotlin 中的 LinearLayout
- ios - 如何让 iOS 15 中的搜索栏默认出现?
- iframe - iframe 可以在主机页面上设置会话存储吗
- mysql - 使用 Python 2.7 将数据连接并插入到 mysql 数据库 5.5
- android - 如何在 Flutter 中使用 SQFLITE 从数据库加载应用程序开始的数据?
- logstash - 按源 IP 过滤 Filebeat 输入
- javascript - 使用 chrome 扩展更改地理位置?
- spring - 由于 java.lang.NoSuchMethodError 无法启动 Spring 应用程序:org.springframework.core.log.LogDelegateFactory.getHiddenLog(Ljava/lang/String;)
- css - 为什么 el-menu-item 设置“浮动:正确”不起作用?