Anbox里的多媒体视频硬解码方案

发表时间:2021/7/27   来源:《基层建设》2021年第9期   作者:肖鹏
[导读] 摘要:传统的anbox里多媒体视频采用软件解码的方式,效率不高。本文揭示了一种在anbox里使用主机硬件解码器的视频解码方案。
        三星电子中国研发中心
        摘要:传统的anbox里多媒体视频采用软件解码的方式,效率不高。本文揭示了一种在anbox里使用主机硬件解码器的视频解码方案。通过移植主机硬解码器的openmax代码至安卓里运行并映射其设备节点,从而实现在anbox里驱动主机上的硬件解码器,提供高效的硬解码能力,使得嵌入式设备上的anbox方案更具商业价值。
        关键字:anbox 多媒体 硬解码 软解码 openmax binder decoder
        Abstract:The paper discloses a method to decode video with the hardware decoder of host in anbox. It’s implemented by porting the hare decoder openmax code into anbox, then drive it with the kernel driver on host.This solution makes the anbox application on embedded device more amazing and valueable.
        1.概述
        Anbox是一款为Linux主机提供安卓系统环境的开源软件,使在非安卓系统的设备上运行安卓应用成为可能,但由于每台主机的硬件解码器配置不同且大多闭源,因此在anbox里播放多媒体视频时,只能选择软解码。由于软解码解码能力有限,无法胜任一些特殊的codec且加重了CPU负载,因此在anbox里实现硬件解码能力显得尤为迫切。
        2.Anbox中硬件解码架构
        如图1,安卓多媒体播放采用安卓特有的binder机制,Mediaplayer创建OMXclient向Media binder server请求OMX服务。编译移植主机硬件解码器的omx component并注册到安卓框架里,通过该component,可以实现视频数据跨平台的硬件解码通道。
 
        图1
        从图1可以看到,HwDecoder openmax的代码是运行在Android系统里的,而HwDecoder内核驱动则是运行在主机内,只要在anbox映射主机硬件解码器设备节点,即可在anbox里共享主机硬件解码能力。
        3.安卓的多媒体架构
        安卓的多媒体框架如图2所示,最上层抽象出Media Codecs给应用层使用;Media Codecs通过binder向Media Player Service请求服务;libstagefright为安卓OMX的中间件,上承应用,下接OMX component,封装了安卓至OMX查询、配置、数据输入、输出等通用接口;libstagefrighhw.so为decoder的OMX DL适配层库文件,它本质是一个wrapper,承接安卓OMX框架与主机decoder OMX DL,该部分为厂家自定义,需要符合安卓OMX框架规范,继承并实现OMXPluginBase相关接口。

        图2
        安卓框架加载主机硬件解码器的流程如图3所示,在HWOMXPlugin(自定义wrapper)中通过dlopen的方式打开硬件解码器的安卓版OMX的库文件lib_OMX_Core.so,把decoder omx的接口加载进安卓统,供libstagefright模块调用,打通安卓OMX框架到decoder的通路。
 
        图3
        4.如何在anbox里使能自定义的OMX硬件解码器
        1)向系统注册自定义的HwDecoder component
        通过分析anbox源码MediaCodecList.cpp可以发现,MediaCodecList的构造函数解析media_codecs.xml中包含的codec配置文件并向系统注册自定义codec,如下所示。
        MediaCodeclist:MediaCodecList(): mInitCheck(NO_ INIT),
        parse TopLevelXMLFile("/system/etc/media_ codecs_ performance.xml", true);
        media_codecs.xml的内容如下所示,把其中带有google的软解码codec注释掉,添加自定义的codec文件,在该文件中定义硬件解码器的componentame,设置该component关联的codec tag(如video/avc),并设置为该codec设置相应的属性。
        <Include href="media_ codecs_ google_ _video.xml" />
        -
        <Include href="media_ codecs_ _xxx_ _video.xml"/>
        系统在启动时根据该配置文件,加载并实例化其中的component。播放视频时,根据视频的codec tag调用相关的解码器实例。
        <Decoders>
        <MediaCodec name="OMx.xx.video_ _decoder.avc" type="video/avc">
        <Limit name="size" min=" 2x2" max="4080x4080" />
        <Limit name="alignment" value="2x2" />
        <Limit name=" block-size" value="16x16" />
        <Feature name="adaptive playback" />
        </MediaCodec>
        </Decoders>
        2)重要库文件
        Libstagefrighthw_omx.so
        从图2可以看到,图中有三个库文件。Libstagefrighthw_omx.so,anbox原生库文件,在这个库里定义了安卓OMXMaster模块的标准接口,OMXMaster继承了OMXPluginBase,向下加载libstagefrighthw.so,如下所示。
        void OMXMaster::addVendorPlugin() {
        addPlugin("/system/lib/libstagefrighthw.so");
        void OMXMaster::addPlugin(const char *libname){
        mVendoribHandle = dlopen(ibname, RTLD_ NOW);
        typedef OMXPluginBase *(*CreateOMXPluginFunc);
        CreateOMXPluginFunc createOMXPlugin=
        (CreateOMXPluginFunc)dlsym(mVendorLibHandle, "createOMXPlugin");
        if (!createOMXPlugin)
        createOMXPlugin=(CreateOMXPluginFunc)dlsym(mVendorLibHandle,
        "ZN7android15createOMXPluginEv");
        if (createOMXPlugin)
        addPlugin((*createOMXPlugin));
        libstagefrighthw.so
        libstagefrighthw.so为厂商解码器OMX代码的wrapper,它继承了OMXPluginBase, 需要用户实现相关虚函数,并将其注册到OMX框架。
        首先,在HWOMXPlugin()里,通过dlopen的方式加载解码器安卓OMX库文件libSDP_OMX_Core.so,把相应的OMX接口赋值给mInit,mDeinit,mComponentNameEnum,mGetHandle,mFreeHandle,mGetRolesOf ComponentHandle,提供安卓OMX框架调用,实现主机decoder OMX到安卓的加载,加载过程如下所示。
        HWOMXPlugin:HWOMXPlugin(): mLibHandle(dlopen("lib_ OMX_ Core.so", RTLD_ NOW)),
        mlnit(NULL),mDeinit(NULL),mComponentNameEnum(NULL),
        mGetHandle(NULL),mFreeHandle(NULL), mGetRolesOfComponentHandle(NUL){
        if (mLibHandle !=NULL) {
        mInit= (InitFunc)dlsym(mLibHandle, "OMX_ Iit");
        mDeinit= (DeinitFunc)dlsym(mLibHandle, "OMX_ Deinit");
        mComponentNameEnum =
        (ComponentNameEnumFunc)dlsym(mLibHandle, "OMX_ ComponentNameEnum");
        mGetHandle = (GetHandleFunc)dlsym(mL ibHandle, "OMX_ GetHandle");
        mFreeHandle=(FreeHandleFunc)dlsym(mLibHandle, "OMX_ FreeHandle");
        mGetRolesOfComponentHandle=
        (GetRolesOfComponentFunc)dlsym(mLibHandle, "OMX_ _GetRolesOfComponent'");
        (*mInit)();
        }
        }
        lib_OMX_Core.so
        该库文件为主机解码器OMX DL层实现,需要用户从主机平台移植到安卓平台,通常有两种方法:
        ①NDK交叉编译
        ②AOSP下编译
        两种方法各有优缺点:NDK编译方式可以复用厂家的make,只要设置交叉编译工具链即可,移植工作量小,但代码不在anbox镜像中,需要手动添加目标文件;AOSP下编译,需要重新书写android平台下的make文件,并将依赖关系整理到AOSP下。生成的目标代码可以直接压进镜像,代码整体性较好。
        5.实验效果对比
        笔者在同一台设备上启用anbox运行芒果TV,分别以谷歌自带的软件解码器和自定义的主机硬件解码器播放了同一个视频,对比效果如图4所示。
 
        图4
        可以发现在使用了硬件解码器后,图像画质会有所增强(soft render画质差),并且主机CPU负载显著下降。
        6.结束语
        Anbox创造之初,是为了在linux的PC设备上实现安卓系统。随着技术发展,越来越多的嵌入式设备具备强大的CPU,内存和GPU,因此在嵌入式设备上运行anbox的需求也越发强烈,但原生的anbox采用视频软解码,无法满足高清视频的解码需要,本文详细介绍一种anbox中共享主机硬件解码器的方法,为anbox里高清视频解码提供一种更为高效的解决方案。
        参考文献
        [1]Wiegand T,Sullivan G J.Overview of the H.264/AVC video coding standard[J].IEEE Trans Circ and Syst for Video Techonol,2003,13(7):560 576.
        [2] Horowitz M,Joch A.H.264/AVC baseline profile decoder complexity analysis[J].IEEE Trans Circ and Syst for Video TechnoI,2003,13(7):704 716.
        [3] Choi S-K,Jeon J—G.Design and implementation of H.264一based video decoder for digital multimedia broad-casting rA].2004 IEEE Int Conf Multimedia and Expo I C J.Taipei,Taiwan,China.2004.149-152.
        [4]Nicolescu D.Ad Hoe Positioning Systems[C]//Proc of IEEE GLO—BECOM’01.[S.1.]:IEEE Press,2001.
        [5]Bahl P.RADAR:An In-building RF—based User Location and Tracking System[c]//Proc of IEEE INFOCOM’00.[S.1.]:IEEE Press,2000.
 
投稿 打印文章 转寄朋友 留言编辑 收藏文章
  期刊推荐
1/1
转寄给朋友
朋友的昵称:
朋友的邮件地址:
您的昵称:
您的邮件地址:
邮件主题:
推荐理由:

写信给编辑
标题:
内容:
您的昵称:
您的邮件地址: