轻量级多媒体文件处理库

本文推荐几个轻量级多媒体处理库。
vlc,ffmpeg,graphics magicka等都太重量级了,如果只是想解析一个多媒体文件然后用到工程里,那么轻量级的库才是首选。

其实不只限于多媒体处理,有许多好用的轻量级的库,见
https://github.com/nothings/single_file_libs

一、图像基本知识

一个像素由(R,G,B)三个值组成,每个值是uint8,范围0-255。(暂时忽略Alpha)
实际存储图片并不会使用三维矩阵,而是一维数组uint8*,数组长度为width * height * channel
给定像素点(x,y)即可迅速确定其在数组中的位置,进而知道其RGB值。
比如对于一个100 * 100的图片,其像素数组长度为100 * 100 * 3,每3个元素表示一个完整像素点
则arr[0], arr[1], arr[2]就是第一个(左上角)像素的R,G,B值
如果增加alpha通道那就是4个uint8表示一个完整像素点,其他同理。0为纯透明,255为完全不透明

如果不理解像素指针uint8_t的意义,则没法使用底层库。因为这些库解析出来的都是uint8_t。

二、stb_image

https://github.com/nothings/stb
只有一个头文件,能够处理所有常见图片格式的读写。
该作者还写了其他的内容,比如处理ogg音频格式的库和处理truetype font的库。

三、pl_mpeg

https://github.com/phoboslab/pl_mpeg

可以解码mpeg1格式的视频文件,分解出音轨和逐帧图像。

注意视频处理与内存的关系。
假设一个mpg是1280*900,时长18秒,很正常的一个数值
完全解析后的容量是
1280 * 900 * 3 * 30 * 18 = 1780MB
图像大小 fps 时长
如果完全解析完存入内存等需要的时候播放,虽然不会延迟但是内存占用太多,会导致更多问题。如果只是streaming,即解析一帧播一帧然后丢弃,虽然内存占用最小化,但是CPU不够强大的场合会卡顿。
如何处理是使用者要考虑的问题。

四、gif_load

https://github.com/hidefromkgb/gif_load

专门处理动态gif,分解出逐帧图像的每帧的秒数

关于gif格式还要说明下,不然解析出来的内容你不知道怎么处理。
一个Gif有全局宽和高表示图像范围,然后每一帧有自己的宽和高以及距离左上角offset,换言之每一帧相当于一个window,占据全部图像大小的一部分。
这样的好处是不变的内容可以不记录在帧数据里,减少占用空间,window之外的沿用之前的像素即可。

Gif的像素点并不用RGB记录,而是index into a color table,每一帧有自己的表,或者用全局表。好处是用一个uint8即可表示RGB三个值。
由于Gif不使用alpha通道,所以为了表示透明需要从0-255里选一个作为透明值,每一帧的透明值都可能不一样。

disposal method辅助指明如何渲染整张图片,这里的渲染是指先依照某种方式打底,然后根据window里记录的像素点信息override。
如果是do not dispose则整张图片沿用前一帧的像素作为基础。
如果是restore to background color则整张图片使用背景色做基础,实际操作中一般都会全透明处理。
如果是restore to previous,则整张图片使用实际渲染之前的像素做基础,在每一帧全渲染的前提下等同于使用上上帧图像。
透明的像素点根据disposal method不同,实际起到的作用也不同,不过本质上都是透过该位置显示另一个颜色。

随着互联网发展出现了透明背景的gif,为了支持该类型gif需要在解析时额外添加alpha通道,即使用RGBA表示一个像素点。
由于不是标准规范,每个lib处理方式不同,此lib的规定为如果mode是restore to background color同时trans != -1,则按照纯透明处理。
还有个interlaced,这是应对网络延迟的一种方法,先显示模糊的全部图像,等数据到了再不断刷新。