首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >avcodec_send_packet和avcodec_receive_frame线程安全吗?

avcodec_send_packet和avcodec_receive_frame线程安全吗?
EN

Stack Overflow用户
提问于 2022-11-03 07:03:11
回答 1查看 23关注 0票数 0

我正在尝试用libav解码器来实现视频解码应用。大多数libav示例都是这样构建的(伪代码):

代码语言:javascript
复制
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译码器流水线,解码性能低。在我的应用程序中的其他限制-我确切地知道,一个接收到的数据包从网络直接对应于一个解码帧。

除此之外,我还想更快地解决问题。为此,我想将这个循环分成两个不同的线程,如下所示:

代码语言:javascript
复制
//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示例中显示的传统投票周期都是无效的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-03 21:41:26

不,这样的线程在libavcodec中是不允许的。

但是,FFmpeg和libavcodec确实支持线程和硬件流水线。但是,这个级别要低得多,并且要求您作为用户,让FFmpeg/libavcodec完成它的任务,而不必担心它:

  • 不从不同线程调用send_packet()receive_frame()
  • AVCodecContext.thread_count设置为线程;
  • 让FFmpeg中的硬件包装器在内部处理流水线,它们比您更清楚该做什么。如果您对此感兴趣,我可以向专家询问更多信息,但我可以向您推荐相关人员。如果
  • 返回AVERROR(EAGAIN),请拨打receive_frame() first
  • ,如果receive_frame()返回AVERROR(EAGAIN),请拨打send_packet() next。H 219F 220

有了正确的thread_count,FFmpeg/libavcodec将并行解码多个帧,并使用多个核心。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74299117

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档