【Android 视频硬件编码】在Native层实现MediaCodec H264 编码 Demon - 实现任意Size尺寸图片的编码
在前文《【Android 视频硬件编码】在Native层实现MediaCodec H264 编码 Demon》中,
我们实现了如何在Native层中对一系列图片进行编码,编码时配置的参数由具体的编码器性能来决定的,因此各机器编码时使用参数可能有所不同。
比如,我当前使用的这个车机的硬件编码器不支持YUV420P 格式,只支持YUV420SP(NV12) 格式,
因此我需要将源数据进行转格式,转成NV12格式后,再输入给到编码器进行编码。
接下来,我们进入正题。
一、引入编码失败的问题
在前文中,我们使用的是1280x720
格式的图片来进行编码的,编码成功。
但当我修改Size 为 1050x540
时,编码器就编码失败了。
图片信息如下:
如下是编码失败的log:
可以看出编码失败的原因是因为,我在送数据进入编码器时送数据失败了。
失败的原因为,我送入的数据大小为 850500,但编码器所需要的大小为 855360,也就是我送入的数据比编码器所需要的少了5000 多个字节,为什么呢?
我们来对比下之前 1280x720 格式时,编码成功时的log,可以看出,送入的数据大小正是编码器所需要的。
二、失败的原因分析
再回到之前的问题,为什么我送入的数据比编码器所需要的少了5000 多个字节?
由于我们目前没有这个车机编码器的详细资料,因此不知道它所支持的长宽规入,以下均是个人猜想。
2.1 猜想一,可不可能单纯填0
猜想一的意思是,将855360的前850500个数据填满,后面的多余数据填0,
这种方法等明天来试下,看看在末尾填0后,能不正常编码,以及,编码后的效果。
2.2 猜想二,编码器对长与宽存存字节对齐(比如4字节对齐等)
有关字节对齐的问题,可以参考下,我之前写 ffmpeg 编码项目时的经验:
《【FFmpeg编码实战】(1)将YUV420P图片集编码成H264视频文件》
如下图:
好,有了上面的思路,我们也来猜想下:
先看下
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了,先下班回家吃饭了,待更新!!!