我正在尝试用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);
}
}上面是伪码。无论如何,在这个传统的循环中,当我等待接收帧完成,然后等待呈现完成,然后等待下一个数据从网络接收到的解码器缓冲区变为空。无HW译码器流水线,解码性能低。在我的应用程序中的其他限制-我确切地知道,一个接收到的数据包从网络直接对应于一个解码帧。
除此之外,我还想更快地解决问题。为此,我想将这个循环分成两个不同的线程,如下所示:
//thread one
while true {
auto packet = receive_packet_from_network();
avcodec_send_packet(packet);
}
//thread two
while true {
auto frame = alloc_empty_frame();
int r = avcodec_receive_frame(&frame);
if (r==0) {
send_to_render(frame);
}目的是将循环分成两个不同的线程,以保证输入的解码器缓冲器始终有足够的数据,大部分都是满的。只有在这种情况下,我想HW解码器,我希望使用将高兴地工作,不断流水线。当然,为了简单起见,我需要线程同步机制,而不是在这里显示。当然,当从avcodec_send_packet()或avcodec_receive_frame()返回EGAIN时,我需要等待其他线程完成其输入缓冲区或获取就绪帧的任务。那是另一个故事。
此外,这种线程解决方案不适用于我的随机分割错误。不幸的是,我找不到任何libav文档明确指出,如果这种方法可接受与否,avcodec_send_packet()和avcodec_receive_frame()调用线程安全与否?
那么,加载HW解码器流水线的最佳方式是什么?对我来说,任何libav示例中显示的传统投票周期都是无效的。
发布于 2022-11-03 21:41:26
不,这样的线程在libavcodec中是不允许的。
但是,FFmpeg和libavcodec确实支持线程和硬件流水线。但是,这个级别要低得多,并且要求您作为用户,让FFmpeg/libavcodec完成它的任务,而不必担心它:
send_packet()和receive_frame();AVCodecContext.thread_count设置为线程;AVERROR(EAGAIN),请拨打receive_frame() firstreceive_frame()返回AVERROR(EAGAIN),请拨打send_packet() next。H 219F 220有了正确的thread_count,FFmpeg/libavcodec将并行解码多个帧,并使用多个核心。
https://stackoverflow.com/questions/74299117
复制相似问题