« 记一个 Bug | 返回首页 | 从数组里删除一个元素 »

在游戏引擎中播放视频

美术同学给我们的游戏做了段片头视频,正要加到产品中去时,才发现我们的引擎居然没有提供视频播放的功能。我想这个东西开源库一大堆,那做起来还不是小菜一碟。可没想到还是折腾了一整天才搞定。

第一件事是考察 License 。结果用的人做多的 ffmpeg 是 GPL 的,不适合我这种商业应用。虽然有一部分功能可以以 LGPL 的方式使用,但是遵守起来也是麻烦一大堆。想了一下还是做罢。我可不想学暴风影音和 QQ Player 那样上耻辱榜

最终考察结果,居然没太多的选择。还是 google 的 vp8 最好。License 最为宽松,所以就去下载了一份 libvpx 的最新版试用。

README 有点老旧,里面说在 Windows 下编译必须 cygwin ,我很听话的在 cygwin 下 build 了一份出来。反正就是个 libvpx.a ,打算复制到 Mingw 里去用。可在 Mingw 里链接却出了问题,缺少 pthread 库。mingw32 是不带这个库的,虽然在网上找了一份 pthread-win32 ,但是看了几眼,被那一大坨 dll 吓怕了,犹豫了一下还是没继续尝试。

重新回头研究了一下 libvpx 的 source ,发现它并不一定要使用 pthread 的 api ,貌似在 windows 下还可以使用 win32 原生 api ,看起来是为 vs 编译准备的。我估摸着 mingw 也能搞定,接着装了份 msys 试了一下,果然 ok。

现在写个玩具播放器还需要一个以 vp8 格式压缩的数据文件。看了一下, libvpx 里带了 ivfenc 。输入是 yuv 格式,输出是 ivf 格式。而 libvpx 主页上没看到 api 文档,只好去读它自带的 simple decode 的代码。看了一眼发现很好理解,用起来还是很简单的。只是这个测试用的 ivf 文件怎么生成略有头痛。

yuv 格式似乎是一种不压缩的 YUV 色彩空间的位图序列。ffmpeg 可以生成。又下了一份 ffmpeg 编译出来,把美术交过来的视频编码成了 .yuv 文件。然后在用 ivfenc 转换成了 .ivf 。

本来想播放一下转换的成果看看先。google 了一下,没有什么现成的软件可以播放之。无奈之下,只好闷头先写播放程序。写出来后怎么都不对,非常郁闷。

开始怀疑是不是 .ivf 压缩错了。好在我曾经有过 jpeg 的编解码经验,对这块有点感觉。猜测到可能是 yuv 文件不对。想了一下,原来 .yuv 文件应该只是一个纯粹的数据流,里面没有任何格式信息。比如视频的帧率,视频的尺寸等等。所以网上很难找到所谓 .yuv 的播放器。而且 ivfenc 在压缩时也必须在命令行指定视频的大小。因为 .yuv 的输入流里根本就没这个信息。一开始还想当然的以为 ivfenc 会根据命令行指定尺寸对数据源做缩放,后来手工计算了一下视频应该有的帧数和实际压缩后帧数严重不符,才发现问题。

同理,.ivf 也仅仅是一图象压缩流。并非完整的视频文件。所以也没有所谓 ivf 的 codec 了。完整的视频文件格式还需要额外的描述信息以及音频流数据等。

明白了这些就知道该怎么做了。用 ffmpeg 输入 .yuv 数据时,可以加上 -f yuv4mpegpipe 生成指定的 yuv 信息,并且指定 -pix_fmts 为 yuv420p ,这个是 ivfenc 认的 yuv 格式。(yuv 有多种组合方式,在 jpeg 的压缩中也是如此)。之后,使用 ivfenc 时指定正确的宽高,就能生成有效的 ivf 文件了。


播放视频的时候通常需要把像素数据从 YUV 转到 RGB 。这个程序我十年前用 MMX 优化过,今天再翻出来用用即可。C 的优化版本也还凑合。今天还 google 到一篇 paper 专门谈这个优化的。有兴趣的同学可以参考一下。

不过在 3d engine 里还有更好的方法:就是利用 GPU 。只需要为 YUV 各创建一张单通道帖图,然后在 ps 里做转换即可。之所以不用一张三通道帖图干这事,是因为默认的 ivf 展开的数据,YUV 是 4:1:1 储存的。

当然单纯播放视频的话,也可以用 YUV 格式的覆盖表面来做。在 DirectX 里容易实现,我还不清楚 OpenGL 里该怎么干。


今天一开始有同学建议我嵌一个媒体播放器或是 Flash player 的控件在 Engine 中。我很不愿意考虑这种方案。不解释了。其实用开源库的方法,实际消耗的人力也没有预想的大。

Comments

你的山寨coc也国产耻辱之一,怎么还有脸笑别人
早已习惯。不多说。
软件和女人一样,当是免费的时间,是最好的时间。。
控件肯定不行,没有代码,有问题不好处理。
上了耻辱榜,真丢人啊。不过耻辱榜地址是什么?
今天也去下了libvpx的sourcecode,他自己的官方主页上有关于如何在windows/vs里面编译的文档的,呵呵
其实我也在网易的一款产品里找到了一些 GNU GPL之类的字样。 我想,这说明同一个公司里的员工对知识产权问题的观念差异是挺大的
为啥要骂QQ?这种羡慕嫉妒恨的心态不好。
另外,libvpx里面的decoder不如ffmpeg中darkshikari新实现的版本: Announcing the world’s fastest VP8 decoder: ffvp8 http://x264dev.multimedia.cx/?p=499
ffmpeg直接压缩vp8,封装为webm(mkv)不就可以了?为啥要用ivf这个恶心的东西?
云风,你做的游戏啥时候能玩到啊!!!!
风风,我爱你!!!
to glds
你可以偷偷D版,你可以心安理得,但你喜欢拿出来炫耀,你很喜欢被鄙视
是的,你们早不知耻辱为何物了
QQ根本不会在意的,你们骂你们的,我们赚我们的钱
qq被骂惯了,早就不觉得耻辱了
恩,不错,支持下。
我觉得若以简单论,使用os的视频播放方案最好了,像光荣那样 只要是给普通人用的os,没有不带媒体播放器的吧
劳烦云大解释下为什么不用FP....效率安全问题?
惊讶于云风十年前的代码还能迅速找到拿出来用。不知道是怎么管理代码的,方便的话共享一下吧,呵呵。
云风大神好厉害
VP8刚刚发布不久,貌似有点专利方面的问题,以下摘自VP8技术分析: Finally, the problem of patents appears to be rearing its ugly head again. VP8 is simply way too similar to H.264: a pithy, if slightly inaccurate, description of VP8 would be “H.264 Baseline Profile with a better entropy coder” . Though I am not a lawyer, I simply cannot believe that they will be able to get away with this, especially in today’s overly litigious day and age. Even VC-1 differed more from H.264 than VP8 does, and even VC-1 didn’t manage to escape the clutches of software patents. Until we get some hard evidence that VP8 is safe, I would be extremely cautious. Since Google is not indemnifying users of VP8 from patent lawsuits, this is even more of a potential problem. But if luck is on Google’s side and VP8 does pass through the patent gauntlet unscathed, it will undoubtedly be a major upgrade as compared to Theora.
耻辱榜里的QQPLAYER和Baofeng Storm是亮点啊
控件肯定不行,没有代码,有问题不好办。
安装msysgit时,自带了一份mingw,里面是gcc4.4,而lib目录下是存在libpthread.a的

Post a comment

非这个主题相关的留言请到:留言本