输出流、剪裁和缩放

输出流

相机子系统针对所有分辨率和输出格式都仅在基于 ANativeWindow 的管道上运行。您可以一次配置多个流,以便将单个帧发送至多个目标,例如:GPU、视频编码器、RenderScript,或应用可见的缓冲区(RAW Bayer 缓冲区、经处理的 YUV 缓冲区或经 JPEG 编码的缓冲区)。

出于优化的目的,这些输出流必须提前配置,而且只有有限的输出流可同时存在。这样一来,就可以预先分配内存缓冲区并配置相机硬件,以便在列出多个或者不同输出管道的情况下提交请求时,不会出现请求延迟执行的情况。

如需详细了解取决于受支持的硬件级别的保证流输出组合,请参阅 createCaptureSession()

剪裁

完整像素阵列的剪裁(用于数字变焦和需要更小 FOV 的其他使用情况)通过 ANDROID_SCALER_CROP_REGION 设置进行传递。这个设置可按需更改,这种方式对于实现平滑的数字变焦至关重要。

该区域被定义为矩形(x 和 y 分别表示宽和高),其中 (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),并假设传感器为 300 万像素级(2000 x 1500 像素阵列),下面展示了针对几个样本剪裁区域,每路视频流的预期输出区域。

剪裁区域:(500、375、1000、750)(宽高比为 4:3)
640x480 视频流剪裁:(500、375、1000、750)(与剪裁区域相同)
1280x720 视频流剪裁:(500、469、1000、562)

crop-region-43-ratio

图 1. 宽高比:4:3

剪裁区域:(500、375、1333、750)(宽高比为 16:9)
640x480 视频流剪裁:(666、375、1000、750)
1280x720 视频流剪裁:(500、375、1333、750)(与剪裁区域相同)

crop-region-169-ratio

图 2. 宽高比:16:9

剪裁区域:(500、375、750、750)(宽高比为 1:1)
640x480 视频流剪裁:(500、469、750、562)
1280x720 视频流剪裁:(500、543、750、414)

crop-region-11-ratio

图 3. 宽高比为 1:1

最后一个示例是宽高比为 1024×1024(方形)的视频流,而不是 480p 视频流:
剪裁区域:(500、375、1000、750)(宽高比为 4:3)
1024x1024 视频流剪裁:(625、375、750、750)
1280x720 视频流剪裁:(500、469、1000、562)

crop-region-43-square-ratio

图 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)

zoom-ratio-2-crop-43

图 5. 缩放级别为 2.0,宽高比为 4:3

缩放比例:2.0;原始视野范围的 1/4
剪裁区域:(0、187、2000、1125)(宽高比为 16:9)
640x480 视频流剪裁:(250、187、1500、1125)(邮筒模式)
1280x720 视频流剪裁:(0、187、2000、1125)(与剪裁区域相同)

zoom-ratio-2-crop-169

图 6. 缩放级别为 2.0,宽高比为 16:9

缩放比例:0.5;原始视野范围的 4 倍(从广角镜头切换到超广角镜头)
剪裁区域:(250、0、1500、1500)(宽高比为 1:1)
640x480 视频流剪裁:(250、187、1500、1125)(信箱模式)
1280x720 视频流剪裁:(250、328、1500、844)(信箱模式)

images/zoom-ratio-0.5-crop-11

图 7. 缩放级别为 0.5,宽高比为 1:1

如上图所示,剪裁区域的坐标系会更改为有效的缩放后视野范围,用矩形和以下尺寸表示:(00activeArrayWithactiveArrayHeight)。这同样适用于 AE/AWB/AF 区域和人脸。此坐标系更改不适用于 RAW 格式拍摄及其相关元数据,例如 intrinsicCalibrationlensShadingMap

我们仍以上述同一示例为例,假设输出视频流 #1 (640x480) 是取景器视频流,则可以通过以下两种设置来实现 2 倍缩放:

  • zoomRatio = 2.0scaler.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。或者,应用可以针对 1.0android.control.zoomRatioandroid.control.aeRegions 设置为 (500, 375, 1000, 750) 的同等区域。