安卓中的硬解码

1,472 阅读2分钟

「这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战

安卓中的硬解码

如果没有做过播放器或者没有同屏经验,会觉得硬解码很陌生,即使每个单词都认识,但拿着它完全不知道从何下手。这篇文章的目的是让大家对硬解码有基本的认识,至少在思想上是明朗的。

硬解码和软解码

所有可以播放的视频,都是有自己的格式的,我们要想播放这些视频,就需要进行按照对应的格式进行解码。 这部分操作被称为解码。

解码又分为两种:硬解码和软解码。

  • 硬解码:利用手机的解码芯片解码,速度快,不发热,缺点是硬件并非统一的平台,适配性不好。比如安卓手机的MediaCodeC

  • 软解码:利用手机CPU进行解码,会发热,优点是有适配很好,比如FFmpeg

这篇文章是讲安卓中的硬解码,也就是MediaCodeC

MediaCodeC

MediaCodeC 实际上相当于是操作多媒体底层库的钥匙,使用MediaCodeC可以驱动底层芯片进行编码或者解码。

引用网上的一张图

image.png 大概意思是编码/解码芯片上有很多处理器,当哪一部分空闲时,就丢进去编码/解码,编码/解码后的数据再返回给MediaCodeC

MediaCodeC 基本使用

MediaCodeC 创建

一般通过以下方式得到MediaCodeC对象


private final static String MIME_TYPE = "video/avc";

MediaCodec codec = MediaCodec.createDecoderByType(MIME_TYPE);

MediaCodeC 配置

配置方法有单独的一个对象称为MediaFormat,通过这个类我们可以设置关键帧、码流、帧率等配置。 代码如下:


final MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, width, height);

format.setInteger(MediaFormat.KEY_BIT_RATE, width * height);

format.setInteger(MediaFormat.KEY_FRAME_RATE, 20);

format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);

MediaCodeC映射到载体

只有数据怎么行,得把数据映射到载体上,才能显示出来。


codec.configure(format, surface, null, 0);

MediaCodeC 获取宽高

通过MediaCodeC获取媒体的宽和高。

程序应该先有默认的宽和高,在码流中如果宽高改变,再去动态修改显示区域的宽和高,达到同比例的效果,进一步的也可以根据宽填充还是根据高填充。


MediaFormat currentFormat = mediaCodec.getOutputFormat();

int mediaW = currentFormat.getInteger("width");

int mediaH = currentFormat.getInteger("height");