我编写了一个简单的视频会议应用程序,该应用程序使用多个线程进行视频和音频混合。我使用libavcodec(ffmpeg)编解码器来混合视频。据我所知,libavcodec使用SSE指令来实现高性能。对于音频混合,我使用一种简单的混合算法,该算法仅添加样本。我已经在C ++中使用sipmle for
循环编写了添加算法,但是现在我想使用如下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)发生冲突?任何建议表示赞赏。
答案 0 :(得分:0)
只要您使用的是现代编译器(不超过10年),并且没有在汇编中进行编码,上下文切换就应该可以。编译器了解目标平台的ABI,因此您不必这样做。
如果您包含了使应用程序崩溃的确切代码,则最可能的原因是对齐问题。将_mm_load_si128
替换为_mm_loadu_si128
,将_mm_store_si128
替换为_mm_storeu_si128
,看是否有帮助。
更新1:另一个可能的原因是SSE版本完成速度过快,这会触发并发错误。尝试添加例如Sleep( 2 )
会在循环后调用,如果视频可以正常运行,则意味着您需要修复在线程之间推送或提取数据的代码。
更新2:正如艾伦指出的那样,数组(缓冲区)的大小可能不是16字节(16 * (nSizeToMix + 7) / 8
)的倍数。这肯定会导致您的应用程序崩溃或内存损坏。