输出流
相机子系统完全基于 ANativeWindow 管道运行,适用于所有分辨率和输出格式。可以一次配置多个流,以将单帧发送到多个目标,例如 GPU、视频编码器、RenderScript 或应用可见的缓冲区(RAW Bayer、已处理的 YUV 缓冲区或 JPEG 编码的缓冲区)。
作为一种优化,必须提前配置这些输出流,并且一次只能存在有限数量的输出流。这样可以预先分配内存缓冲区并配置相机硬件,以便在提交请求时,如果列出了多个或不同的输出管道,则在满足请求时不会出现延迟或延迟。
有关取决于受支持硬件级别的有保证的流输出组合的更多信息,请参阅 createCaptureSession()
。
裁剪
完整像素阵列的裁剪(用于数码变焦和其他需要较小 FOV 的用例)通过 ANDROID_SCALER_CROP_REGION 设置进行通信。这是一个按请求设置,并且可以按请求更改,这对于实现平滑数码变焦至关重要。
区域定义为一个矩形 (x, y, width, height),其中 (x, y) 描述矩形的左上角。该矩形在传感器有效像素阵列的坐标系上定义,(0,0) 是有效像素阵列的左上角像素。因此,宽度和高度不能大于 ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY 静态信息字段中报告的尺寸。最小允许宽度和高度由 HAL 通过 ANDROID_SCALER_MAX_DIGITAL_ZOOM 静态信息字段报告,该字段描述了最大支持的缩放因子。因此,最小裁剪区域宽度和高度为
{width, height} = { floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[0] / ANDROID_SCALER_MAX_DIGITAL_ZOOM), floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[1] / ANDROID_SCALER_MAX_DIGITAL_ZOOM) }
如果裁剪区域需要满足特定要求(例如,它需要从偶数坐标开始,并且其宽度/高度需要为偶数),则 HAL 必须进行必要的四舍五入,并在输出结果元数据中写出最终使用的裁剪区域。 同样,如果 HAL 实现了视频防抖,则必须调整结果裁剪区域以描述应用视频防抖后实际包含在输出中的区域。通常,使用相机的应用程序必须能够根据裁剪区域、图像传感器的尺寸和镜头焦距来确定其接收的视野。
由于裁剪区域适用于所有码流,而这些码流可能具有与裁剪区域不同的宽高比,因此每个码流使用的确切传感器区域可能小于裁剪区域。 具体而言,每个码流应保持正方形像素及其宽高比,方法是最小限度地进一步裁剪定义的裁剪区域。如果码流的宽高比宽于裁剪区域,则应进一步垂直裁剪码流;如果码流的宽高比窄于裁剪区域,则应进一步水平裁剪码流。
在所有情况下,码流裁剪都必须在完整裁剪区域内居中,并且每个码流相对于完整裁剪区域仅进行水平或垂直裁剪,绝不会两者都进行。
例如,如果定义了两个码流,一个 640x480 码流(4:3 宽高比)和一个 1280x720 码流(16:9 宽高比),则以下演示了在假设的 3 MP(2000 x 1500 像素阵列)传感器上,针对几个示例裁剪区域的每个码流的预期输出区域。
裁剪区域:(500, 375, 1000, 750)(4:3 宽高比)
640x480 码流裁剪:(500, 375, 1000, 750)(等于裁剪区域)
1280x720 码流裁剪:(500, 469, 1000, 562)

图 1. 4:3 宽高比
裁剪区域:(500, 375, 1333, 750)(16:9 宽高比)
640x480 码流裁剪:(666, 375, 1000, 750)
1280x720 码流裁剪:(500, 375, 1333, 750)(等于裁剪区域)

图 2. 16:9 宽高比
裁剪区域:(500, 375, 750, 750)(1:1 宽高比)
640x480 码流裁剪:(500, 469, 750, 562)
1280x720 码流裁剪:(500, 543, 750, 414)

图 3. 1:1 宽高比
以及最后一个示例,一个 1024x1024 正方形宽高比码流,而不是 480p 码流
裁剪区域:(500, 375, 1000, 750)(4:3 宽高比)
1024x1024 码流裁剪:(625, 375, 750, 750)
1280x720 码流裁剪:(500, 469, 1000, 562)

图 4. 4:3 宽高比,正方形
重新处理
重新处理 RAW Bayer 数据支持提供了对原始图像文件的额外支持。此支持允许相机管道处理先前捕获的 RAW 缓冲区和元数据(先前记录的整个帧),以生成新的渲染 YUV 或 JPEG 输出。
变焦
对于运行 Android 11 或更高版本的设备,应用程序可以通过 ANDROID_CONTROL_ZOOM_RATIO
设置使用相机的变焦(数码和光学)。
变焦比率定义为浮点因子。应用程序可以使用 ANDROID_CONTROL_ZOOM_RATIO
来控制变焦级别,并使用 ANDROID_SCALER_CROP_REGION
进行水平和垂直裁剪以实现与原生相机传感器不同的宽高比,而不是使用 ANDROID_SCALER_CROP_REGION
进行裁剪和变焦。
多摄像头系统可能包含多个具有不同焦距的镜头,用户可以通过在镜头之间切换来使用光学变焦。在以下情况下,使用 ANDROID_CONTROL_ZOOM_RATIO
具有优势
- 从广角镜头变焦到长焦镜头:与
ANDROID_SCALER_CROP_REGION
的整数值相比,浮点比率提供更高的精度。 - 从广角镜头缩小到超广角镜头:
ANDROID_CONTROL_ZOOM_RATIO
支持缩小 (<1.0f),而ANDROID_SCALER_CROP_REGION
不支持。
变焦比率:2.0;原始视野的 1/4
裁剪区域:(0, 0, 2000, 1500)(4:3 宽高比)
640x480 码流裁剪:(0, 0, 2000, 1500)(等于裁剪区域)
1280x720 码流裁剪:(0, 187, 2000, 1125)

图 5. 2.0 倍变焦,4:3 宽高比
变焦比率:2.0;原始视野的 1/4
裁剪区域:(0, 187, 2000, 1125)(16:9 宽高比)
640x480 码流裁剪:(250, 187, 1500, 1125)(pillarboxed)
1280x720 码流裁剪:(0, 187, 2000, 1125)(等于裁剪区域)

图 6. 2.0 倍变焦,16:9 宽高比
变焦比率:0.5;原始视野的 4 倍(从广角镜头切换到超广角镜头)
裁剪区域:(250, 0, 1500, 1500)(1:1 宽高比)
640x480 码流裁剪:(250, 187, 1500, 1125)(letterboxed)
1280x720 码流裁剪:(250, 328, 1500, 844)(letterboxed)

图 7. 0.5 倍变焦,1:1 宽高比
从上面的图表中可以看出,裁剪区域的坐标系更改为变焦后的有效视野,并由以下尺寸的矩形表示:(0
, 0
, activeArrayWith
, activeArrayHeight
)。这同样适用于 AE/AWB/AF 区域和人脸。此坐标系更改不适用于 RAW 捕获及其相关元数据,例如 intrinsicCalibration
和 lensShadingMap
。
使用上面相同的假设示例,并假设输出码流 #1 (640x480) 是取景器码流,则可以通过以下两种方式之一实现 2.0 倍变焦
zoomRatio = 2.0
,scaler.cropRegion = (0, 0, 2000, 1500)
zoomRatio = 1.0
(默认),scaler.cropRegion = (500, 375, 1000, 750)
对于应用程序将 android.control.aeRegions
设置为取景器视野的左上四分之一,请将 android.control.aeRegions
设置为 (0, 0, 1000, 750)
,并将 android.control.zoomRatio
设置为 2.0
。或者,应用程序可以将 android.control.aeRegions
设置为 (500, 375, 1000, 750)
的等效区域,用于 android.control.zoomRatio
为 1.0
。