【Android 视频硬件编码】在Native层实现MediaCodec H264 编码 Demon - 实现任意Size尺寸图片的编码

时间:2024-06-01 08:03:26

【Android 视频硬件编码】在Native层实现MediaCodec H264 编码 Demon - 实现任意Size尺寸图片的编码

在前文《【Android 视频硬件编码】在Native层实现MediaCodec H264 编码 Demon》中,
我们实现了如何在Native层中对一系列图片进行编码,编码时配置的参数由具体的编码器性能来决定的,因此各机器编码时使用参数可能有所不同。

比如,我当前使用的这个车机的硬件编码器不支持YUV420P 格式,只支持YUV420SP(NV12) 格式,
因此我需要将源数据进行转格式,转成NV12格式后,再输入给到编码器进行编码。


接下来,我们进入正题。

一、引入编码失败的问题

在前文中,我们使用的是1280x720 格式的图片来进行编码的,编码成功。

但当我修改Size 为 1050x540 时,编码器就编码失败了。
图片信息如下:
【Android 视频硬件编码】在Native层实现MediaCodec H264 编码 Demon - 实现任意Size尺寸图片的编码
如下是编码失败的log:
【Android 视频硬件编码】在Native层实现MediaCodec H264 编码 Demon - 实现任意Size尺寸图片的编码

可以看出编码失败的原因是因为,我在送数据进入编码器时送数据失败了。
失败的原因为,我送入的数据大小为 850500,但编码器所需要的大小为 855360,也就是我送入的数据比编码器所需要的少了5000 多个字节,为什么呢?

我们来对比下之前 1280x720 格式时,编码成功时的log,可以看出,送入的数据大小正是编码器所需要的。
【Android 视频硬件编码】在Native层实现MediaCodec H264 编码 Demon - 实现任意Size尺寸图片的编码


二、失败的原因分析

再回到之前的问题,为什么我送入的数据比编码器所需要的少了5000 多个字节?
由于我们目前没有这个车机编码器的详细资料,因此不知道它所支持的长宽规入,以下均是个人猜想。


2.1 猜想一,可不可能单纯填0

猜想一的意思是,将855360的前850500个数据填满,后面的多余数据填0,
这种方法等明天来试下,看看在末尾填0后,能不正常编码,以及,编码后的效果。


2.2 猜想二,编码器对长与宽存存字节对齐(比如4字节对齐等)

有关字节对齐的问题,可以参考下,我之前写 ffmpeg 编码项目时的经验:
【FFmpeg编码实战】(1)将YUV420P图片集编码成H264视频文件

如下图:


【Android 视频硬件编码】在Native层实现MediaCodec H264 编码 Demon - 实现任意Size尺寸图片的编码


好,有了上面的思路,我们也来猜想下:

先看下 850500 850500 850500 是如何计算来的,我们知道YUV420P 格式为 YYYYYYYY UU VV,因此数据大小是 长x宽的 3/2 倍。
也就是,
850500 = 1050 × 540 + 1050 × 540 4 + 1050 × 540 4 = 1050 × 540 × 3 2 850500 = 1050 \times540 + \frac{1050\times540} 4 + \frac{1050\times540} 4 = \frac{1050\times540\times3} 2 850500=1050×540+41050×540+41050×540=21050×540×3


好,接下来,来看下编码器所需要的 855360 855360 855360 是怎么来的,先来强行拼凑下:
855360 = 1056 × 540 × 3 2 855360 = \frac{1056\times540\times3} 2 855360=21056×540×3




将近7点30了,先下班回家吃饭了,待更新!!!