音视频基础--Android生成HEIF文件
![](http://static.careerengine.us/api/aov2/https%3A_%7C__%7C_mmbiz.qpic.cn_%7C_mmbiz_jpg_%7C_CmsibKlb9Ekg7jMmZYaLpQ0OUYUib64eGaddfJTU2ib0dVRia16pRzh5W4RoHTDTzxdaPLPV6Md8M3vWIb57nPhiaaA_%7C_0%3Fwx_fmt%3Djpeg.jpg)
本文系微信公众号和知乎专栏《MediaStack》原创文章,欢迎大家关注,随时进行交流。
之前几篇文章介绍了Android平台解析HEIF图像格式的流程
然后小伙伴不淡定了:只是解析难度不大吧,也把生成HEIF文件的流程走一下呀!!! 这个还真有,今天我们看看具体实现,完成这个小伙伴这个很好的建议。
Java层可以通过HeifWriter进行HEIF文件写文件的操作调用,具体用法参考如下链接:
https://developer.android.com/jetpack/androidx/releases/heifwriter
https://developer.android.com/reference/androidx/heifwriter/HeifWriter
如果要调用相关内容,需要导入如下库:
dependencies {
implementation"androidx.heifwriter:heifwriter:1.1.0-alpha01"
}
HeifWriter介绍
此类将一个或多个静止图像(相同尺寸)写入 heif 文件。它目前支持三种输入模式:INPUT_MODE_BUFFER、INPUT_MODE_SURFACE 或 INPUT_MODE_BITMAP。使用该类编写 heif 文件的一般顺序(伪代码)如下:
1)构造 writer:HeifWriter heifwriter = new HeifWriter(...);
2)如果使用surface输入方式,获取输入surface:Surface surface = heifwriter.getInputSurface();
3)调用start:heifwriter.start();
4)根据选择的输入模式,使用以下方法之一添加一个或多个图像:heifwriter.addYuvBuffer(...); 或 heifwriter.addBitmap(...); 或者渲染到之前得到的surface
5)调用stop: heifwriter.stop(...);
6)关闭writer:heifwriter.close(); 具体用法请参考各个方法的文档。
我们依次看一下相关流程:
(1)构造Writer
HeifEncoder使用 HEVC 编码器将图像编码为与 HEIF 兼容的样本。它目前支持三种输入模式:INPUT_MODE_BUFFER、INPUT_MODE_SURFACE 或 INPUT_MODE_BITMAP。输出格式和样本在 HeifEncoder.Callback.onOutputFormatChanged(HeifEncoder, MediaFormat)
和 HeifEncoder.Callback.onDrainOutputBuffer(HeifEncoder, ByteBuffer) 中发回。如果客户端请求使用网格,每个图块将单独发回。HeifEncoder 与 HeifWriter 分开,因为一些更高级的用例可能希望直接在 HeifEncoder 之上构建解决方案。(例如,将静止图像和视频轨道混合到一个容器中)。
配置 heif 编码器
相关参数:width - 图像的宽度;height - 图像的高度;useGrid - 是否将图像编码为图块。如果启用,将自动选择平铺大小;quality – 一个介于 0 和 100(含)之间的数字,100 表示此实现支持的最佳质量(通常会导致文件更大);inputMode – 此编码会话的输入类型;handler - 如果不为 null,客户端将接收处理程序循环器上的所有回调。否则,客户端将在我们创建的 Looper 上收到回调;cb – 从 heif 编码器接收各种消息的回调。
(2)输入模式,
如果选择surface模式,需要进行Surface的获取,主要的输入模式有三种方式,每一种模式对应不同的选项:
(3)Start启动
HeifWriter启动,在该函数中主要是设置标志位,同时调用HeifEncoder的启动函数。
当然和其他的编解码器一样的限制:只能被调用一次,否则出现异常。
(4)添加图片
三种模式对应的调用接口如下:
addYuvBuffer
int: 中定义的YUV格式ImageFormat,目前只支持YUV_420_888。
byte: 包含 YUV 数据的字节数组。如果格式有多个平面,则必须将它们连接起来。
通过acquireEmptyBuffer接口获取一个空输入缓冲区并将数据复制到其中。在发送输入 EOS 之前,这将阻塞直到数据被复制。输入 EOS 发送后,立即返回。
如果有可用的输入和编解码器缓冲区,则例程复制一个图块。必须在处理 MediaCodec 回调的处理程序循环器上调用。
熟悉Media Codec框架的童鞋看到这里应该非常熟悉了。就是通过mediaCodec框架完成原始数据输入,编码后再通知app相关数据完成,主动或被动获取。
getInputSurface
检索输入Surface以便进行编码,前提是如果配置了surface。
addBitmap
Bitmap:要添加到文件中的位图。
调用HeifEncoder addBitmap接口完成输入bitmap和encoderEGLSurface绑定
(5)stop停止
同步停止 heif Writer。如果Writer没有成功完成写入,则抛出异常。成功返回后:
- 对于buffer和bitmap输入模式,停止前将写入所有发送的图像。
- 对于Surface输入模式,需要分情况讨论:setInputEndOfStreamTimestamp被调用,则写入时间戳等于或早于 这个指定的时间戳的图像会写入,否则如果
setInputEndOfStreamTimestamp(long)
从未调用过,stop 将阻塞直到接收到足够数量的图像。 timeoutMs long:等待编写器完成的最长时间(以微秒为单位),零表示无限期等待。
(6)close关闭
停止和释放 writer 的例程必须在接收 heif 编码器回调的同一个 looper 上调用。
(7)其他内容
还有其他一些callback函数进行妥善处理,不然解码后outputbuffer的处理
MPEG4Write
通过MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC 格式在framework中走的流程是MPEG4Write相关流程,该部分很多大佬在讲解extractor时候有介绍,我们这边简单说明一下:
首先我们介绍一下Android平台输出所支持类型:主要包括MPEG4, WEBM, 3gpp,HEIF,OGG等。说实话Android对于这个类型支持力度还是略显不足,需要各个厂商或者app开发者进行各种形式兼容和优化。
MP4文件生成时会判断一下输出格式是否是MPEG4,3GPP,或者HEIF文件格式,否则不做处理。
可以看到在writeFtypBox时候完成heic文件格式写入:
之后依次调用writeFilelevelMetaBox和writeMoovBox等接口完成相关box的写入操作,而各类box的写入完全按照格式标准进行,基本是读取时候的反操作:
我们看主要接口:writeMoovBox的调用过程,如下
writeFilelevelMetaBox接口主要完成各个meta信息汇总写入操作:
writeMoovBox主要完成moov西悉尼吸入,以及各个track的信息写入:
writeTrackHeader一次完成各个box的数据写入:
实例代码log
正好手头上有一台平板,用的是rk的平台,所以就跑了一个demo相关流程的log部分截图如下,Android12的代码会走codec2的接口。
我是一枚爱跑步的程序猿,很多内容属于自学内容,文中难免会出现一些错误或者不准确的地方,恳请大家批评指正。
关键词
数据
编码
图像
内容
函数
最新评论
推荐文章
作者最新文章
你可能感兴趣的文章
Copyright Disclaimer: The copyright of contents (including texts, images, videos and audios) posted above belong to the User who shared or the third-party website which the User shared from. If you found your copyright have been infringed, please send a DMCA takedown notice to [email protected]. For more detail of the source, please click on the button "Read Original Post" below. For other communications, please send to [email protected].
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。