Android的软解码和硬解码

Android  2020年10月12日 pm7:19发布4年前 (2020)更新 城堡大人
92 0 0

MediaCodec里有接口可以枚举所有解码格式,每种编码可能都有多个解码器。

MediaCodec mediaCodec = MediaCodec.createDecoderByType("video/avc");

我的应用里面接收的是H264编码数据,所以我选取的是video/avc,我们可以看一下MediaCodec.createDecoderByType()枚举了哪些解编码格式:

>  /**
>      * Instantiate a decoder supporting input data of the given mime type.
>      *
>      * The following is a partial list of defined mime types and their semantics:
>      * <ul>
>      * <li>"video/x-vnd.on2.vp8" - VP8 video (i.e. video in .webm)
>      * <li>"video/x-vnd.on2.vp9" - VP9 video (i.e. video in .webm)
>      * <li>"video/avc" - H.264/AVC video
>      * <li>"video/mp4v-es" - MPEG4 video
>      * <li>"video/3gpp" - H.263 video
>      * <li>"audio/3gpp" - AMR narrowband audio
>      * <li>"audio/amr-wb" - AMR wideband audio
>      * <li>"audio/mpeg" - MPEG1/2 audio layer III
>      * <li>"audio/mp4a-latm" - AAC audio (note, this is raw AAC packets, not packaged in LATM!)
>      * <li>"audio/vorbis" - vorbis audio
>      * <li>"audio/g711-alaw" - G.711 alaw audio
>      * <li>"audio/g711-mlaw" - G.711 ulaw audio
>      * </ul>
>      *
>      * @param type The mime type of the input data.
>      */
>     public static MediaCodec createDecoderByType(String type) {
>         return new MediaCodec(type, true /* nameIsType */, false /* encoder */);
>     }

可以看到我选的”video/avc” - H.264/AVC video是一种H264的解码方式,但并不能证明我使用的就一定是硬解码

我们先来看一下Android系统中解码器的命名,软解码器通常是以OMX.google开头的。硬解码器通常是以OMX.[hardware_vendor]开头的,比如TI的解码器是以OMX.TI开头的。当然还有一些不遵守这个命名规范的,不以OMX.开头的,那也会被认为是软解码器。

判断规则见frameworks/av/media/libstagefright/OMXCodec.cpp:

static bool IsSoftwareCodec(const char *componentName) {
    if (!strncmp("OMX.google.", componentName, 11)) {
        return true;
    }

    if (!strncmp("OMX.", componentName, 4)) {
        return false;
    }

    return true;
}

其实MediaCodec调用的是在系统中注册的解码器,系统中存在的解码器可以很多,但能够被应用使用的解码器是根据配置来的,即/system/etc/media_codecs.xml。这个文件一般由硬件或者系统的生产厂家在build整个系统的时候提供,一般是保存在代码的device/[company]/[codename]目录下的,例如device/samsung/tuna/media_codecs.xml。这个文件配置了系统中有哪些可用的codec以及,这些codec对应的媒体文件类型。在这个文件里面,系统里面提供的软硬codec都需要被列出来。

也就是说,如果系统里面实际上包含了某个codec,但是并没有被配置在这个文件里,那么应用程序也无法使用到。

在这个配置文件里面,如果出现多个codec对应同样类型的媒体格式的时候,这些codec都会被保留起来。当系统使用的时候,将会选择第一个匹配的codec。除非是指明了要软解码还是硬解码,但是Android的framework层为上层提供服务的AwesomePlayer中在处理音频和视频的时候,对到底是选择软解还是硬解的参数没有设置。所以虽然底层是支持选择的,但是对于上层使用MediaPlayer的Java程序来说,还是只能接受默认的codec选取规则。

但是Android提供的命令行程序/system/bin/stagefright在播放音频文件的时候,倒是可以根据参数来选择到底使用软解码还是硬解码,但是该工具只支持播放音频,不支持播放视频。

一般来说,如果系统里面有对应的媒体硬件解码器的话,系统开发人员应该是会配置在media_codecs.xml中,所以大多数情况下,如果有硬件解码器,那么我们总是会使用到硬件解码器。极少数情况下,硬件解码器存在,但不配置,我猜只可能是这个硬解码器还有bug,暂时还不适合发布,所以不用使用。

PS: MTK Android 9.0的路径是[/vendor/etc/media_codecs.xml]

文章来源

  1. 请问android使用MediaCodec进行解码,就是硬解码吗?软解码和硬解码的优先级是怎样的?

 历史上的今天

  1. 2024: 去除USB权限效验弹框(0条评论)
  2. 2022: Cygwin安装教程简介(0条评论)
  3. 2019: 铁凝:幸福就在此刻(0条评论)
版权声明 1、 本站名称: 笔友城堡
2、 本站网址: https://www.biumall.com/
3、 本站部分文章来源于网络,仅供学习与参考,如有侵权,请留言

暂无评论

暂无评论...

随机推荐

SeekBar和Viewpager冲突

Android开发中滑动冲突非常常见,基本是是嵌套时出现触摸事件被拦截或者无法传递到。比如SeekBar和Viewpager,SeekBar和ListView等下面是的内容是摘抄于《SeekBar和Viewpager的滑动冲突的解决办法(其他滑动冲突可参考)》的方法,当然我也百度和谷歌过其他的答...

Java反射机制及IoC原理

这篇讲解的不错,摘抄于此。感谢《Java反射机制及IoC原理》一. 反射机制概念主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。在java中,只要给定类的名字, 那么就可以通过反射机制来获得类的所有信息。反...

启动startService()分析(3)

闲话少说,接上一篇《Android 6.0 启动startService()源码分析(2)》10.9 ActiveServices.bumpServiceExecutingLocked 发送SERVICE_TIMEOUT_MSG用来判断是否ANR   private final void ...

Android ListView子item高度定长固定值无效问题详解

前言最近做显示音乐列表信息时,发现ListView的Item布局中固定的高度失效了,怎么设置这个高度都失效。参考网用和自己折腾过程,记录一下,防止下次忘记。总结整理一下原因:1. LayoutInflater.inflate(int resource, ViewGroup root)...

ListView的item中当文本出现阿拉伯语时会显示怪异

前言测试反馈有些歌曲名字中如果存在阿拉伯语,列表显示时就出现显示右边怪异的问题。总所周知,阿拉伯语显示在右边的。比如עברית_xi bo lai yu.mp3العربية_a la bo yu.mp3فارسی_bo si yu.mp3显示如下 a la ...

王小波:卡尔维诺与未来的一千年

朋友寄来一本书,卡尔维诺的《未来千年备忘录》,我正在看着。这本书是他的讲演稿,还没来得及讲,稿也没写完,人就死了。这些讲演稿分别冠以如下题目:轻逸、迅速、易见、确切和繁复。还有一篇"连贯",没有动笔写,所以我整天在捉摸他到底会写些什么,什么叫做"连贯"。卡尔维诺指出,在未来的一千年里,文学会继续繁荣...