与Libavcodec一起使用SSE指令

时间:2019-01-03 07:25:28

标签: c++ sse libavcodec video-conferencing

我编写了一个简单的视频会议应用程序,该应用程序使用多个线程进行视频和音频混合。我使用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)发生冲突?任何建议表示赞赏。

1 个答案:

答案 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)的倍数。这肯定会导致您的应用程序崩溃或内存损坏。