我试图捕捉Android的视图为位图,并将其保存为。mp4文件。
我正在使用MediaCodec编码位图和MediaMuxer将它们混合成。mp4。
使用YUV420p颜色格式,我希望MediaCodec的输入缓冲区的大小为resWidth * resHeight * 1.5
,但高通的OMX.qcom.video.encoder.avc
给我的比这更多(无论我选择什么分辨率)。我相信它希望我在输入字节流中做一些对齐,但我不知道如何找出它到底希望我做什么。
当我在Nexus 7(2013)上使用高通的编解码器将数据紧密地打包在输入缓冲区中时,我得到的结果是:https://www.youtube.com/watch?v=JqJD5R8DiC8
这个视频是由在Nexus 10上运行的同样的应用程序制作的(编解码器OMX.Exynos.AVC.Encoder
): https://www.youtube.com/watch?v=90RDXAibAZI
所以看起来在错误的视频中亮度平面是正确的,但是色度平面发生了什么对我来说是一个谜。
我准备了一个最小的(2类)工作代码示例来暴露这个问题:https://github.com/eeprojects/MediaCodecExample
您可以通过运行此应用程序获得上面显示的视频(如果您的设备使用高通的编解码器,则会有相同的工件)。
在缓冲区中存储yuv420有多种方法;您需要检查您选择的单个像素格式。MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar
和MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar
实际上是相同的,称为平面或简称为I420,而MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar
, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar
和MediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar
称为半平面或NV12。
在半平面中,你不必分离U和V的平面,但你有一个平面,上面有一对交错的U和V。
看到关于如何为半平面格式填充缓冲区的示例:https://android.googlesource.com/platform/cts/+/jb-mr2-release/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java(第925-949行)