文 / Jeff Gong, Sahil Dhanju, Chih-Chiang Lu, Yueshi Shen

编者按:超过220万创作者在Twitch发布海量的视频,这对实时转码业务造成了巨大压力,Twitch团队通过优化多线程的转码服务以及Intel QuickSync的支持,实现了比FFmepg性能提升65%,并降低80%总体拥有成本。Twitch团队通过博客介绍了这一实现,LiveVideoStack对本文进行了摘译,点击『阅读原文』访问英文博客。同时,Yueshi Shen将在12月8-9日的ArchSummit 2017北京大会上详细介绍实现过程。

FFmpeg的1-in-N-out流水线。为什么它无法处理前面讨论的技术问题?

FFmpeg如何以编程方式处理需要单个输入来生成多个转码和(或)转封装输出的实例? 我们可以通过直接剖析FFmpeg最新3.3版的源代码,来了解其线程模型和转码流水线。

在顶层ffmpeg.c文件中,transcode()函数(第4544行)不断循环并重复调用transcode_step()函数(第4478行),直到其输入信息被完全处理,或用户中断执行为止。Transcode_step()函数封装了主要的流水线,并在许多其他即时步骤之间编排诸如文件I / O、过滤、解码和编码等动作。

在初始设置阶段,init_input_threads()(第4020行)函数被调用,并将根据输入文件的数量,产生一些新的线程来处理这些输入。

if (nb_input_files == 1) {  return 0;}for (i = 0; i < nb_input_files; i++) {  ...  ret = av_thread_message_queue_alloc(&f->in_thread_queue, f->thread_queue_size, sizeof(AVPacket));    // line 4033}

在第4033行中(如上所示),我们看到产生的线程数量完全由输入的数量决定。也就是说,这意味着FFmpeg将只使用一个线程来处理1-in-N-out的场景。

在get_input_packet()函数(第4055行)中,只有当输入文件的数量大于1时,才会调用多线程伴随函数get_input_packet_mt()(第4047行)。get_input_packet_mt()函数可以以非阻塞的方式从消息队列中读取输入帧。否则的话,我们需要使用av_read_frame()(第4072行)来每次读取并处理一个帧。

#if HAVE_PTHREADS  if (nb_input_files > 1) {     get_input_packet_mt(f, pkt);  }#endif  return av_read_frame(f->ctx, pkt);

如果我们跟踪帧数据一直到流水线结束,我们发现它进入到process_input_packet()函数(行2591)中,该函数对帧数据进行解码并通过所有适用的过滤器进行处理。时间戳校准和字幕处理的工作也在这个函数中进行。最后,在函数返回之前,已解码的帧被复制到每个相关的输出流。

for (i = 0; pkt && i < nb_output_streams; i++) {  ...  // check constraints  do_streamcopy(ist, ost, pkt);    // line 2756}

最后,transcode_step()函数调用reap_filters()函数(第1424行)来循环遍历每个输出流。reap_filters()函数的for循环负责收集缓冲区中待处理的帧,并将这些帧进行解码,然后封装到一个输出文件中。

// reap_filters line 1423for (i = 0; i < nb_output_streams; i++) { // loop through all output streams  ...  // initialize contexts and files  OutputStream *ost = output_streams[i];  AVFilterContext *filter = ost->filter->filter;  AVFrame filtered_frame = ost->filtered_frame;  while (1) { // process the video/audio frame for one output stream     ...  // frame is not already complete     ret = av_buffersink_get_frame_flags(filter, filtered_frame, …);     if (ret < 0) {        ...  // handle errors and logs        break;     }     switch (av_buffersink_get_type(filter)) {     case AVMEDIA_TYPE_VIDEO:        do_video_out(of, ost, filtered_frame, float_pts);     case AVMEDIA_TYPE_AUDIO:        do_audio_out(of, ost, filtered_frame);     }     ...}

通过跟踪这条流水线,我们知道这些帧是如何通过单个线程的上下文顺序进行处理的,从中我们能看到一些冗余。我们可以得出结论,既然1-in-N-out的转码流模型对我们来说是最有价值的,那么FFmpeg仅使用单线程来输出结果则可能并不理想。FFmpeg文档也建议我们在实际用例中,并行地启动多个FFmpeg实例或将更有意义。在这里,我们关键的一点认识是,既然此工具(FFmpeg)没有提供多线程功能,它就无法满足Twitch流媒体服务的严格需求,那么我们就无法随心所欲地使用它。

基准测试

TwitchTranscoder是我们为解决前面讨论的技术问题而开发的内部软件。它已被广泛运用于我们的生产中,每天24小时地处理数万个并发直播流。

为了确定TwitchTranscoder每天在转码任务上的表现是否会优于FFmpeg,我们进行了一系列基本的基准测试。在我们的测试中,我们对两个工具使用相同的Twitch直播流以及有相同预设、配置文件、比特率和其他标志的1080p60视频文件。每个视频源都被转码成我们通常使用的典型的720p60,720p30,480p30,360p30和160p30。

我们的假设是,FFmpeg对于输入文件的转码速度比TwitchTranscoder要慢,甚至可能无法跟上直播的速度。

图9,10和11中的结果比较了TwitchTranscoder与FFmpeg的执行时间。实验表明,即使在我们处理相同及更多(除了上面指定的栈之外,还提供仅音频转码,缩略图生成等等)任务的情况下,我们的转码器对于离线转码一直有绝对优势。

对于输出单个版本的720p60,FFmpeg稍快,这是因为TwitchTranscoder要处理如上所述的更多任务。当版本的数量增加时,TwitchTranscoder的多线程模型表现出更大的优势,这些优势帮助它超越了FFmpeg。观察Twitch完整的ABR梯度,与FFmpeg相比,TwitchTranscoder节省了65%的执行时间。

图9:TwitchTranscoder与FFmpeg转码时间比较,实验1

图10:TwitchTranscoder与FFmpeg转码时间比较,实验2

图11:TwitchTranscoder与FFmpeg转码时间比较,实验2

我们通过比较在出问题前,一台机器上最多能够运行多少个FFmpeg的并行实例来进行实时流转码测试。这里可能发生的问题包括帧丢失、视频伪影等。在我们的生产服务器中,我们能够支持多个通道同时进行转码,同时,更多的通道被转封装。不幸的是,运行多个FFmpeg实例会导致一系列影响转码输出的错误,并且需要更高的CPU利用率(请参见图12中的屏幕截图)。

图12:FFmpeg运行多个实例时的错误消息

结论

在本文中,我们将FFmpeg作为实时流RTMP- to-HLS的转码器进行了研究,并提供了有关如何操作该工具的信息。该解决方案部署起来很简单,但有一些技术问题值得注意,比如段错位、不必要的性能损失,以及缺乏支持我们产品功能的灵活性等。因此,我们实现了自己内部的转码器软件栈TwitchTranscoder,它运行在一个定制的线程模型中,并可以在一个进程中输出N个处理版本。

LiveVideoStack招募全职技术编辑和社区编辑

LiveVideoStack是专注在音视频、多媒体开发的技术社区,通过传播最新技术探索与应用实践,帮助技术人员成长,解决企业应用场景中的技术难题。如果你有意为音视频、多媒体开发领域发展做出贡献,欢迎成为LiveVideoStack社区编辑的一员。你可以翻译、投稿、采访、提供内容线索等。

通过contribute@livevideostack.com联系,或在LiveVideoStack公众号回复『技术编辑』或『社区编辑』了解详情。

Twitch如何实现转码比FFmpeg性能提升65%?(下)相关推荐

  1. Twitch如何实现转码器比FFmepg性能提升65%?(上)

    文 / Jeff Gong, Sahil Dhanju, Chih-Chiang Lu, Yueshi Shen 译 / 王鸿蒙 编者按:超过220万创作者在Twitch发布海量的视频,这对实时转码业 ...

  2. 从 FFmpeg 性能加速到端云一体媒体系统优化

    简介:7 月 31 日,阿里云视频云受邀参加由开放原子开源基金会.Linux 基金会亚太区.开源中国共同举办的全球开源技术峰会 GOTC 2021 ,在大会的音视频性能优化专场上,分享了开源 FFmp ...

  3. Xilinx+AWS F1+VP9带来30倍实时转码性能提升

    在实时.海量.高并发视频的场景下,FPGA加速找到了自己的发展空间,弥补了VP9在编码复杂度方面的不足,专利费的优势也得以体现. 文 / Ant 在上周圣何塞举行的XDF(Xilinx开发者论坛)上( ...

  4. 通信系统未编码、卷积码与格雷码的仿真性能比较

    通信系统未编码.卷积码与格雷码的仿真性能比较 论文+代码+仿真结果:下载地址 以上仿真结果可知: 1.未编码.卷积编码和格雷码三种编码,经PSK调制后加AWGN(高斯白噪声),在经过解调和解码得出来的 ...

  5. (2,1,3)卷积码与一种QC-LDPC码的译码性能对比

    在上一篇文章中 BPSK调制下(2,1,3).(2,1,6)卷积码与QC-LDPC码译码性能和抑制突发噪声性能对比(MATLAB实现) 重写了(2,1,3)卷积码与一种QC-LDPC码的译码性能对比代 ...

  6. 【转】HashMap,ArrayMap,SparseArray源码分析及性能对比

    HashMap,ArrayMap,SparseArray源码分析及性能对比 jjlanbupt 关注 2016.06.03 20:19* 字数 2165 阅读 7967评论 13喜欢 43 Array ...

  7. SpringBoot 实现大文件视频转码(转码基于FFMPEG实现)

    最近项目需要将用户上传的视频如果不是MP4格式,需要全部转码为MP4格式的,这里我通过FFMPeg进行大文件视频转码的实现. 一.安装FFMPeg 首先我们需要在机器上安装FFMPeg用于我们的视频转 ...

  8. 视频分辨率转码(ffmpeg)

    接触视频业务时,视频分辨率是不得不面对的一个重要问题,目前无论是各大视频网站或者小型网站.系统都拥有视频分辨率这个最为基础的功能,用户可以根据自己网络情况播放不同分辨率的视频,除了一些根据用户网络情况 ...

  9. 视频转码 via FFmpeg

    视频转码 via FFmpeg FFmpeg 简介 FFmpeg 命令行转码 FFmpeg API 转码 Transcoding 流程图 Transcoding 代码 open_input_file ...

最新文章

  1. LeetCode实战:二叉树的最大深度
  2. python编程爱心-使用Python画出小人发射爱心的代码
  3. java两个对象赋值_一起学Java(二十六)----- 对象之间赋值
  4. 怎么让电脑屏幕一直亮着_电脑屏幕总是闪烁?试试这个方法
  5. oracle的解析計劃,Oracle中获取执行计划的几种方法分析
  6. 学习写 Makefile
  7. 国人不能再过度迷信开源软件
  8. com口驱动_四足机器人FOC驱动器篇1:Odrive Moco接口板套件介绍
  9. 双击java安装包没有反应_eclipse安装包双击没反应怎么回事?
  10. Godot入门遇到的一些问题汇总
  11. ExMobi移动应用平台 烽火星空引领企业移动信息化
  12. 怎样关闭域用户电脑中的趋势杀毒软件
  13. 电子商务里的P2P、O2O、P2C、B2C、B2B、C2C是什么?
  14. 微信小程序 - 自定义组件中类似页面 onShow 的页面显示就触发的生命周期钩子函数(页面回退时更新数据常用, 例如回退页面更新子组件数据, 回退更新子组件中 data 内容)
  15. 离线高清卫星地图SDK及解决方案
  16. windows 下 搭建 ElasticSearch 环境
  17. 动态规划-规划兼职工作
  18. 单机Eureka构建步骤
  19. 基于Qt的上古神器-Qt Cryptographic Architecture (QCA)加密库介绍
  20. 三、队列:优先队列+循环队列(击鼓传花算法)

热门文章

  1. MIT 学生挑战新泽西索取挖矿程序源代码的要求
  2. JavaScript 语言基础知识点图示
  3. 破解sina新浪邮箱密码
  4. HDU - 4866 Shooting(主席树+扫描线)
  5. CodeForces - 1348C Phoenix and Distribution(思维)
  6. Java接口四个类四则运算_用JAVA设计一个接口,声明有关算术运行的方法,并创建四个应用该接口的类,分别进行+-*/四则运算...
  7. 京东 你访问的页面需要验证证书_SSL证书安全认证有什么原理?
  8. Duplicate entry ‘211‘ for key ‘PRIMARY‘异常解决
  9. php重定向和伪静态,Apache301重定向和伪静态设置教程(wp程序为例)
  10. C++中Struct和Class的区别