MLT的学习理解


MLT是一个开源的多媒体库,我们的音视频编辑工具,是使用它作为底层支持,某司的‘快剪辑’pc版和安卓版,也是用的它。

MLT简介

它的GitHub地址,这个库比较老了,现在只有一个作者在维护,可能这种库关注的人比较少,所以只有几百个star。想快速上手这个库,可以去看Shotcut的源码,这个Shotcut是一个多轨道视频编辑工具,底层用的就是MLT,UI用的是Qt。MLT用的插件化的设计,它的核心是纯C写的,只依赖标准库和pthread,主要采用的是生产者(producer)和消费者(consumer)模型,模块功能扩展可以有producer,consumer,filter,transition只要遵循核心接口里面的API就行了。MLT的功能模块,用到了很多知名的音视频处理库,像FFmpeg,JACK,Movit,SDL,SOX,libvorbis,都是以插件的形式扩展的。MLT核心虽然是用c语言写的,但是还有一颗面向对象的心,它在最上层的mlt_properties_s结构体里面添加了引用计数,然后它用C++对这些结构体面向对象封装了一下,在类的构造和析构函数里面分别引用计数加一减一,在c代码里面也有一些引用计数操作,但总的来说这个库还是存在内存泄露的,我们自己的项目和Shotcut都有,我们发现关闭一个视频编辑project之后,内存并没有释放,一些对象在我们看来已经完全没有被引用,虽然也调了析构函数,但是引用计数还是没清零,后面我们在关闭编辑作品之后,强制释放大的内存,能大概释放8成左右的内存,还有一部分没有定位到(这个内存释放在后面会讲到)。Shotcut也没有做到关闭一个project,释放内存,所以内存比较小的机器,操作多了会出现崩溃。

项目集成

参照Shotcut的源码,集成MLT还是比较容易的,MLT的编译环境是用32位和64位的mingw,下载那些依赖库,顺利编译,编译完成后,测试一下melt.exe。
关于UI层,我们做的时候考虑的便利性,没有直接选用QT,而采用了PYQT,虽然开发的速度是提高了不少,但是也为后面埋下了一些坑。
在Python层调用c++和c,MLT使用SWIG生成Python接口。在视频播放的过程中的,MLT的sdl_audio consumer会在on_frame_show回调mlt_frame,这个回调方法是在异步线程里面执行的,我们需要在这个线程里面调用Python层的方法,把mlt_frame传过去,首先必须先加GIL全局锁,然后才能调用Python方法,因为Python只允许同时一时刻,只能有一个线程占用解释器。这样虽然是可以正常调用,但是会有一个问题,这个回调不断的加全局锁,抢夺解释器,在播放的过程中,如果快速进行一些UI操作,很容易导致卡顿转圈,然后崩溃,用户体验非常不好。后面改进的方法就是避免在c++异步线程频繁调用Python代码,我们把QWidget的窗口句柄传入MLT,然后直接用opengl,绘制图形,这样就可以播放,也不会造成卡顿了。

3D文字

MLT里面的webvfx利用webkit引擎,可以直接渲染网页,所以先前用的是three.js绘制了3d文字,然后加一些简单的文字动画,但是视频加了这种3d文字之后,会变的十分卡顿,fps只有十左右。webvfx生成3d文字图像,然后借助transition和视频图像融合,这些都是在cpu里面进行了,非常消耗时间;另外加载字体的时候导致内存占用也非常大,偶尔还会导致崩溃,简直做不下去了。后面产品方案让我重新做一套3d文字,使用的是opengl+freetype重新做了一套,因为以前总是做移动方向的,所以对opengl接口比较熟悉,d3d不太熟练,所以采用opengl。目前各种动画效果已经做出来了,但是有两点做的不太好,一是当时没有考虑文字要换行,二是光照效果做的不太满意。后面继续优化吧。
未完待续。。。。

05-06 04:19