Android平台ffmpeg的硬解库生成

        一直想写一篇文章记录我近几天摸索ffmpeg在Android平台生成硬解码库遇到的问题。马上就要放假,再不写估计就更没有思路写下去。这只是我的一些个人研究,失误之处在所难免,如果您觉得有不对的地方还请留言指正!

Android上做H264实时视频裸流解码我们一直使用ffmpeg的软解码,整体效果还是可以的,目前在小米2做到解码720P恒定码率 15fps(一般为了保证视频的实时性,解码慢就会导致丢帧,直至丢I帧,所以通过看视频效果是很明显的),分析数据发现每帧解码时间为30ms左右,大部分低于30ms,看到这个30ms有人可能觉得就算解码线程负责渲染,那也可以达到解码20-25fps!其实我当时看到部分打印时间的时候也是这么认为的,但是当我发现其中有些帧的解码时间达到60ms,甚至100ms时才知道原因。我没有深究是I帧或是P帧解码花了这么长的时间,也考虑双线程解码(毕竟多核CPU手机普遍),可以像流水线一样达到缩短周期的效果(这也同时涉及到解码后的PICTURE排序渲染的问题)。但是我更清楚软解有其天生的局限,不能像硬解一样可以明确解码resolution多少帧就可以做到解码多少帧,而且这个ffmpeg软解码库已经打开asm,neon等优化开关,已经是我做的最好的优化版本。

         上面啰嗦了一大堆,下面继续!

         前天我发现vlc播放我们设备的720P rtsp流CPU占有率普遍低于20%,而我们的普遍在30%-45%,当时我就想弄清楚为什么,毕竟VLC player里面明确指出他用到了ffmpeg/libav,虽然我做不了代码级的优化,但也不至于效率差这么多。我当时想VLC应该是使用了硬解码库,我就查了它的几个lib,果然使用硬解码。以前看过一篇文章说到VLC等一些APP使用Android硬解,并且说虽然这是不公开的API但是你依然可以放心使用(是啊,Android升级了你也等着升级吧!!!)。当时因为项目紧张,软解码一直使用而且效果也被接受,公司老人都认为存在兼容性问题等几个因素,所以放弃了研究,毕竟又要赶又要好是很难的事,贸然使用难免引起满天的投诉。

为了代码的最小改动,为了达到更低CPU占用率,我使用tools/build_libstagefright生成硬解码的ffmpeg库,打开文件一看正好是基于android-ndk-r7b android-9,这也是我们的jni要求的最低系统要求。赋值NDK, 对./configure做了一些改动编译吧,很快几个不大的*.a出来了,连接成so真机运行,avcodec_find_decoder_by_name("libstagefright_h264")怎么返回NULL,真不敢相信自己的眼睛,这可是教材式的生成法啊!到网上查了一把,几乎都是如此,只不过ndk不同,而且r8的居多,这就纳闷了,看so依赖没有发现硬解码库。分析avcodec_find_decoder_by_name发现这个函数会查链表。ffmpeg使用宏REGISTER_DECODER注册解码器,但是要CONFIG_##X##_DECODER宏打开了才行,然后就查看config.h, config.mak对比软解码的配置,发现确实没有打开,./configure加入enable-decoder=libstagefright_h264才会使CONFIG_LIBSTAGEFRIGHT_H264_DECODER=yes,这样生成库支持硬解码。当然也可以直接调用硬解码而不用ffmpeg。

        记得为不同版本的系统生成库!!!


如果生成的时候提示 “libstagefright_h264 not found”,请将enabled libstagefright_h264  && require_cpp libstagefright_h264 改为 enabled libstagefright && require_cpp libstagefright_h264。

本文的开发环境为:ubuntu10, android-ndk-r7b, ffmpeg-2.5.3

写了这么多,文笔不好,还请理解。

你可能感兴趣的:(流媒体)