更新:这看起来与此相关:Image data from Android camera2 API flipped & squished on Galaxy S5 - 我认为这是一个错误,因为Nexus 5/6正常工作,因此无需获取完整的传感器大小,然后手动裁剪以达到所需的宽高比,也可能不使用“支持”的输出尺寸!
问题:
编解码器输出的大小正确。但结果因设备而异:
没问题,有人会说。也许表面不是精确地以指定的宽度和高度创建的,或者其他任何东西(即使输出大小是专门为MediaCodec.class目标提取的)。
因此,我创建了一个OpenGL上下文,为它生成了一个纹理,一个SurfaceTexture,将其默认缓冲区大小设置为相机输出大小,并使用纹理创建了一个Surface。我不会详细介绍将其绘制到TextureView或返回到MediaCodec的EGL表面。结果是相同的 - Camera2捕获请求仅为某些分辨率输出失真图像。 深入挖掘:在updateTexImage之后立即在SurfaceTexture上调用getTransformMatrix - 矩阵始终是标识矩阵,如预期的那样。
所以,这里真正的问题是相机没有捕获所提供的目标表面的大小。因此,解决方案是获得相机捕获的实际尺寸,其余的是纯GL矩阵变换以正确绘制。但是 - 我怎么得到它?
注意:使用旧的Camera API,具有与目标完全相同的“预览尺寸”和相同的表面(MediaCodec或自定义的) - 一切都很精细!但是我不能使用旧的相机API,因为它已被弃用,并且似乎最大捕获大小为1080p,而Camera2 API超出了这个范围,我需要支持4k录制。
答案 0 :(得分:2)
我遇到了类似的问题,模型SM-A7009
,api等级21,传统的camera2设备。
预览被拉伸,surfaceTexture.setDefaultBufferSize
无效,框架将在预览开始时覆盖这些值。
StreamConfigurationMap.getOutputSizes(SurfaceTexture.class)
报告的预览尺寸并非全部受支持。
只支持其中三个。
$ adb shell dumpsys media.camera |grep preview-size
preferred-preview-size-for-video: 1920x1080
preview-size: 1440x1080
preview-size-values: 1920x1080,1440x1080,1280x720,1056x864,960x720,880x720,800x480,720x480,640x480,528x432,352x288,320x240,176x144
系统转储信息列出了许多预览尺寸,在检查完所有预览尺寸后,我发现只支持1440x1080
,640x480
,320x240
。
支持的预览尺寸均为1.33333
比例。它们与CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE
报告的比率相同。
所以我认为在API 21中使用传统camera2 api的一些三星设备中存在一个错误。
解决方案是使用弃用的相机API制作这些设备。
希望有人能够到达这里。
答案 1 :(得分:1)
所以是的,这是三星设备上的一个错误。
通常,当您在输出上要求多个不同的宽高比时会发生这种情况,并且特定于设备的摄像机代码会在裁剪时自行跳过并正确缩放所有这些宽高比。您可以通过确保所有请求的大小具有相同的宽高比来避免它。
分辨率可能实际上是你要求的 - 但是它被缩放得不正确(你可以用有问题的ImageReader来测试它,你可以在那里找到一个明确的缓冲区。)
我们正在为Android合规性测试添加额外的测试,以确保不会继续发生这些延伸的输出。