avcodec_send_packet与avcodec_receive_frame是否线程安全?HW解码器性能优化咨询
关于Libav多线程解码的线程安全与性能优化问题
我正在基于Libav解码器开发视频解码应用,大多数Libav示例采用的伪代码结构如下:
while true { auto packet = receive_packet_from_network(); avcodec_send_packet(packet); auto frame = alloc_empty_frame(); int r = avcodec_receive_frame(&frame); if (r==0) { send_to_render(frame); } }
这种单线程循环存在明显性能瓶颈——等待网络包接收、帧渲染完成的过程中,解码器输入缓冲区会处于空状态,无法充分利用硬件解码器的流水线能力,解码效率偏低。我的应用有个明确限制:每个从网络接收的packet对应一个解码后的frame。
为了提升性能,我打算把循环拆分为两个独立线程,伪代码如下:
// 线程一:负责网络包接收与送入解码器 while true { auto packet = receive_packet_from_network(); avcodec_send_packet(packet); } // 线程二:负责从解码器取出解码帧并渲染 while true { auto frame = alloc_empty_frame(); int r = avcodec_receive_frame(&frame); if (r==0) { send_to_render(frame); } }
拆分线程的核心目标是让解码器输入缓冲区始终保持充足的待处理数据,尽可能填满缓冲区,让硬件解码器能持续以流水线模式工作。我会添加必要的线程同步机制(为简化伪代码未展示),也会处理avcodec_send_packet()或avcodec_receive_frame()返回EAGAIN时的等待逻辑。
但这个多线程方案出现了随机段错误,我在Libav官方文档里没找到明确说明——这种用法是否可行?avcodec_send_packet()和avcodec_receive_frame()这两个函数是否线程安全?
另外,我还想了解充分利用硬件解码器流水线的最佳实践,显然Libav示例里的传统轮询循环效率不高。
内容的提问来源于stack exchange,提问作者nckm
相关产品推荐
相关产品推荐

