更新:这看起来与此有关:来自 Android camera2 API 的图像数据在 Galaxy S5 上翻转和压扁- 我认为这是一个错误,因为 Nexus 5/6 工作正常,需要获得完整的传感器尺寸然后手动裁剪以达到所需的纵横比,最好不要使用“支持”的输出尺寸!
问题:
- 使用 Camera2 API 获取相机的特征,并提取适合 MediaCodec.class 的输出大小
- 使用合适的相机输出尺寸之一创建 MediaCodec 输入表面。将输出提供给一些 MediaMuxer 或其他任何东西,以查看输出。
- 使用编解码器创建的表面作为目标启动相机捕获请求。
编解码器输出具有正确的大小。但结果因设备而异:
- Nexus 5/6:在 Android 5/6 上一切正常。
- 搭载Android 5.1的三星平板:某些分辨率下,图像明显拉伸,说明摄像头输出分辨率与表面尺寸不匹配。开始旋转相机时变得非常明显 - 图像变得越来越倾斜,因为它没有与 X/Y 轴对齐。对于其他一些分辨率,输出正常。这里没有与大小或纵横比相关的模式。
没问题,有人会说。也许表面不是完全按照指定的宽度和高度创建的,或者其他什么(即使输出大小是专门为 MediaCodec.class 目标提取的)。
因此,我创建了一个 OpenGL 上下文,为其生成了一个纹理,一个 SurfaceTexture,将其默认缓冲区大小设置为相机输出大小,并使用该纹理创建了一个 Surface。我不会深入讨论将其绘制到 TextureView 或返回到 MediaCodec 的 EGL 表面的血腥细节。结果是相同的 - Camera2 捕获请求仅针对某些分辨率输出失真图像。深入挖掘:在 updateTexImage 之后立即在 SurfaceTexture 上调用 getTransformMatrix - 正如预期的那样,矩阵始终是单位矩阵。
所以,这里真正的问题是相机没有以提供的目标表面的大小进行捕捉。因此,解决方案是获取相机正在捕获的实际尺寸,剩下的就是纯 GL 矩阵变换以正确绘制。但是 - 我怎么得到它?
注意:使用旧的 Camera API,具有完全相同的“预览尺寸”和与目标相同的表面(MediaCodec 或自定义) - 一切都很好!但我不能使用旧的相机 API,因为它已被弃用,而且似乎最大捕获大小为 1080p,而 Camera2 API 超出了这个范围,我需要支持 4k 录制。