GoPlay 原理详解

GoPlay是一款基于FFmpeg/OpenGL ES 2.0 的iOS播放器。支持FFmpeg内嵌的所有格式。而且可以自定义各种滤镜, 包括VR、水印等。

前沿

关于iOS视频播放,苹果提供的AVPlayer性能是非常出色的,但是有个缺点,就是支持播放的格式并不多,仅仅支持mp4/mov/ts等有限的几种格式。显然业界中比较知名的jikplayer确实弥补了这种缺陷,然而ijkplayer是在FFmpeg/ffplay的基础上进行开发的,最终是通过SDL2.0进行显示。在当前大环境下,VR、水印、贴图、九宫格等滤镜盛行,在ijkplayer中默认是支持avfilter滤镜的,但是并没有支持GPU滤镜;那么有没有一种办法可以播放AVPlayer不支持格式的视频,又能够在视频上无限制的加滤镜,例如GPUImage那么方便那么丝滑的做法呢?上面两个痛点也就是GoPlay解决的问题。

原理

关于格式支持

关于格式支持,采用了业界比较出名的FFmpeg解封装不同的视频格式;在解码阶段,如果开启了VideoToolBox硬解码,那么就采用iOS的硬解码方式,否则自动切换到FFmpeg的软解码方式。

关于滤镜支持

为了方便滤镜的接入,滤镜包括滤镜链的实现都采用了GPUImage类似的做法,如果使用过GPUImage,那么就可以无缝的切换到GoPlay,同时可以根据GPUImage的已有滤镜自定义滤镜,无限扩展自己的滤镜库。GoPlay和GPUImage的滤镜类比如下表。

GOPlayGPUImage
输入FFMovieGPUImageMovie
滤镜FFFilterGPUImageFilter
输出显示FFViewGPUImageView

运行流程

基本流程

GoPlay主要有5个线程(包括主线程),其中OpenGL ES渲染、滤镜都是在一个统一的异步线程中处理,在这方面与GPUImage的处理稍有不同。异步线程可以防止阻塞UI界面,串行可以防止线程间加锁从而导致的性能损耗。线程模型如下。

  • 解封装线程 -- FFmpeg解封装,读取packet,分发到视频解码线程和音频解码线程

  • 视频解码线程 -- 将packet解码成frame,并保存到队列缓存中

  • 音频解码线程 -- 将packet解码成frame,并保存到队列缓存中

  • OpenGL ES渲染、滤镜处理线程

    • 从video缓存队列中取出数据帧,并且在GPU中从YUV转换成RGB,然后传递给下一级滤镜链,并最终显示

关于音视频同步

在业界中,普遍没有认识到音频视频两者的同步算法是控制学的问题,而仅仅停留在谁快谁慢的问题上。在现实中,音频和视频的PTS的误差是客观存在的,我们需要通过一种控制学算法实现音频和视频的相对同步,需要考虑到累积误差的存在,在相对范围内,同步算法是具有自我调节能力的,当超出某个范围了,那么就需要丢帧了,否则会影响观感。在这么多开源项目中,FFmpeg/ffplay实现了这种思想。

关于丢帧算法

如果真正理解了音视频同步算法,那么丢帧的做法就很简单了,当超出了音视频同步算法的调节范围,而且是视频帧慢于音频帧很多,那么此时就需要丢调视频帧。

关于全景图像显示

全景图像是将一张平面图片映射到一个球面上。本质上也是一种滤镜处理,即要处理好顶点坐标和纹理坐标的映射关系。

关于ArcBall控制

ArcBall本质上是将二维平面上的滑动转换成三维立体球的转动,具体的做法以屏幕中心为球心,画一个球。在屏幕中滑动时,就将滑动的点映射到球面上,如果滑动的范围超出了球的范围,那么就映射到最靠近球面的点上。根据起始点的四元数和终点的四元数的差值(求逆),就可以得到旋转的角度。

关于滤镜链

滤镜链的思路来源于GPUImage,但多路滤镜的处理情况并没有沿袭GPUImageTwoInput之流的做法。在多路滤镜的处理上,水印滤镜中进行了一种尝试。

总结

关于GoPlay的相关原理基本上到这里结束了。感兴趣的可以在GoPlay中找到相关的实现,当然也可以提BUG一起讨论。

转载于:https://juejin.im/post/5cd3f38fe51d45475716251a

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GOM Player Plus 是一款官方号称全球最受欢的高清多媒体播放器,是 GOM Player 的专业版升级版,功能最为强悍,全面兼容AVI、MP4、MP3、MKV、 FLV、WMV、MOV等主流音视频格式,使用 GOM Player Plus 播放视频时除了可随时调整视讯的亮度、对比与饱和度之外,还内建了影片画面撷取功能与批次影片抓图功能,更特别的是威航软件园提供的gom player 激活版还提供了【区段迴圈】功能,可让我们重複播放指定时间的影音内容,对于学语言或重播重要场景等使用需求很有帮助。另外也提供了【探索】功能让我们用更快的速度跳著看片,更可支援快播、慢播等特殊用法。(百度云盘分享密码:bcxo) GOM Player Plus 在功能与操作介面上都相当不错,对于一般影片的解码能力也都相当好,如果播放影片时电脑中找不到可用的影音解码器,GOM Player Plus 还可支援线上搜寻、下载解码器的功能,帮电脑下载安装适用的解码器来播影片。尤其它把视讯、音讯、字幕、播放等控制功能额外整合到另外一个按【F7】就能开启的【控制面板】上,让我们在调整影片的相关播放功能时更快、更方便。 GOM Player Plus 的参数设定的环节,我们也可手动调整或启用/禁用个别的滤镜、解码器,声音的部份还提供了去除人声、人声增强等特殊应用,对于混响效果与 3D 环绕果也可手动调整。整体来说可设定、调整的部份还算完整,且版面配置很人性化,不会太过杂乱难用,gom player 激活版是一款非常强悍的高清视频播放工具。 GOM Player Plus(高清视频播放器)
可以使用Qt的信号和槽来实现这两个案例。首先,你需要创建一个类来表示你自己,假设叫做"Me"。在这个类中,你可以定义两个信号,一个是"callMe()",表示同学叫你的信号,另一个是"goPlay(QString)",表示出去玩的信号,并且传递一个参数来表示要进行的活动。 在Me类的头文件 (.h) 中,你可以这样定义信号和槽: ```cpp #include <QObject> class Me : public QObject { Q_OBJECT public: explicit Me(QObject *parent = nullptr); signals: void callMe(); void goPlay(QString activity); public slots: void handleCall(); }; ``` 在Me类的实现文件 (.cpp) 中,你可以这样实现槽函数: ```cpp #include "me.h" Me::Me(QObject *parent) : QObject(parent) { connect(this, &Me::callMe, this, &Me::handleCall); } void Me::handleCall() { qDebug() << "同学叫我了"; emit goPlay("玩"); } ``` 现在,你可以在应用程序的主窗口中创建一个Me对象,并连接信号和槽: ```cpp #include <QApplication> #include <QMainWindow> #include <QPushButton> int main(int argc, char *argv[]) { QApplication a(argc, argv); QMainWindow window; QPushButton button("叫我"); Me me; QObject::connect(&button, &QPushButton::clicked, &me, &Me::callMe); QObject::connect(&me, &Me::goPlay, [&window](QString activity){ qDebug() << "出去" << activity; if (activity == "玩") { qDebug() << "去爬山"; } }); window.setCentralWidget(&button); window.show(); return a.exec(); } ``` 在这个例子中,当点击按钮时,会发出"callMe()"信号,Me类中的handleCall()槽函数会被调用。在handleCall()中,你可以添加你想要执行的操作,并通过发射"goPlay()"信号来指示出去玩的活动。在主窗口中,我们连接了Me类的"goPlay()"信号,并在lambda表达式中处理这个信号,输出相应的活动。 这样,当同学叫你时,你就会出去玩,并且根据参数决定是玩还是爬山。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值