Android Camera2 —CameraDevice API详解

一、概述    

    CameraDevice类是Android设备上连接的单个摄像头的表示,允许以高帧率对图像捕获和后处理进行精细控制。为了访问摄像头设备,应用程序必须在其清单中声明Camera权限。给定的摄像头设备可以提供CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL中定义的几个级别的支持。如果设备支持LEGACY级别,则摄像头设备处于向后兼容模式,并具有最小的camera2 API支持。如果设备支持LIMITED级别,则Camera2暴露的功能集大致相当于旧的Camera API,尽管具有更清晰和更高效的界面。如果设备支持EXTERNAL级别,则该设备是可移动的摄像头,提供了与LIMITED级别类似但稍微少一些的功能。实现FULL或LEVEL3级别支持的设备,比旧的摄像头API提供了大大提高的功能。如果应用程序需要完全级别的设备才能正常工作,请在清单中声明“android.hardware.camera.level.full”功能。

二、方法

/**
获取该摄像头设备的ID。
这与为 CameraManager.openCamera 提供的 ID 相匹配,以实例化此相机设备。
此 ID 可用于通过 CameraManager.getCameraCharacteristics 查询相机设备的固定属性。
即使设备已关闭或遇到严重错误,也可以调用此方法。
@return 该相机设备的 ID
*/
public abstract String getId();

/**

为新的捕获请求创建一个 CaptureRequest.Builder,并使用目标用例的模板进行初始化。 这些设置被选择为特定相机设备的最佳选项,因此不建议对不同的相机设备重复使用相同的请求; 创建一个特定于该设备和模板的构建器,并根据需要覆盖设置。

Param:
templateType – 选择此请求的用例的枚举。 并非所有设备都支持所有模板类型。 有关详细信息,请参阅每种模板类型的文档。
Return:
用于捕获请求的构建器,使用该模板的默认设置进行初始化,并且没有输出流
Throws:
IllegalArgumentException – 如果该设备不支持 templateType。
CameraAccessException – 如果相机设备不再连接或遇到致命错误
IllegalStateException – 如果相机设备已关闭

*/

public abstract CaptureRequest.Builder createCaptureRequest(@RequestTemplate int templateType)
        throws CameraAccessException;

/**

为新的捕获请求创建一个 CaptureRequest.Builder,并使用目标用例的模板进行初始化。 此方法允许客户端传递物理摄像机 ID,这些 ID 可用于自定义特定物理摄像机的请求。 这些设置被选择为特定逻辑相机设备的最佳选项。 如果传递了额外的物理相机 ID,那么它们也将使用相同的设置模板。 客户端可以通过调用CaptureRequest.Builder.setPhysicalCameraKey进一步修改各个相机设置。
单独的物理相机设置仅适用于使用相应物理相机 ID 输出配置 OutputConfiguration.setPhysicalCameraId 初始化的相机会话,并且相同的输出目标也通过 CaptureRequest.Builder.addTarget 附加在请求中。
如果附加了有效的物理相机设置,则任何逻辑相机流的输出都未定义。

Params:
templateType – 选择此请求的用例的枚举。 并非所有设备都支持所有模板类型。 有关详细信息,请参阅每种模板类型的文档。 physicalCameraIdSet – 一组物理相机 ID,可用于自定义特定物理相机的请求。
Return:
用于捕获请求的构建器,使用该模板的默认设置进行初始化,并且没有输出流
Throws:
IllegalArgumentException – 如果此设备不支持 templateType,或者物理 id 参数之一与逻辑相机 id 匹配。
CameraAccessException – 如果相机设备不再连接或遇到致命错误
IllegalStateException – 如果相机设备已关闭

*/

@NonNull
public CaptureRequest.Builder createCaptureRequest(@RequestTemplate int templateType,
        Set<String> physicalCameraIdSet) throws CameraAccessException {
    throw new UnsupportedOperationException("Subclasses must override this method");
}

/**

使用聚合所有支持参数的 {@link SessionConfiguration} 辅助对象创建新的 {@link CameraCaptureSession}。

活动捕获会话确定相机设备针对每个捕获请求的潜在输出surfaces。 给定的请求可以使用全部或仅部分输出。 创建 CameraCaptureSession 后,可以使用 {@link CameraCaptureSession#capture capture}、{@link CameraCaptureSession#captureBurst captureBurst}、{@link CameraCaptureSession#setRepeatingRequest setRepeatingRequest} 或 {@link CameraCaptureSession#setRepeatingBurst setRepeatingBurst} 提交请求

*/

public void createCaptureSession(SessionConfiguration config) throws
CameraAccessException {
    throw new UnsupportedOperationException("No default implementation");
}
/**
初始化特定于设备的扩展增强相机捕获会话。
扩展会话可用于启用特定于设备的操作模式,例如 CameraExtensionCharacteristics.EXTENSION_NIGHT 或 CameraExtensionCharacteristics.EXTENSION_HDR。 这些模式不如完整的相机 API 灵活,但可以访问更复杂的处理算法,这些算法可以捕获多帧burst以生成单个输出图像。 要查询此设备上的可用扩展,请调用 CameraExtensionCharacteristics.getSupportedExtensions()。此方法还将触发内部处理管道的设置,以进行扩展增强预览和多帧静态捕捉。该方法还将触发内部处理的设置,用于扩展增强预览和多帧静态捕获的管道。
如果调用此方法时先前的 CameraCaptureSession 已存在,则先前的会话将无法再接受新的捕获请求并将被关闭。 在前一个会话上发出的任何正在进行的捕获请求都将在会话关闭之前完成。
CameraExtensionSession 将处于活动状态,直到客户端调用 CameraExtensionSession.close() 或创建新的相机捕获会话。 在这两种情况下,所有内部资源都将被释放,连续重复的请求将停止,并且任何挂起的多帧捕获请求将被刷新。
请注意,CameraExtensionSession 目前最多支持两种多帧捕获surface格式:所有扩展都将支持 ImageFormat.JPEG,而 ImageFormat.YUV_420_888 可能受支持,也可能不支持。 客户端必须使用 CameraExtensionCharacteristics.getExtensionSupportedSizes(int, int) 查询多帧捕获格式支持。 对于重复请求,CameraExtensionSession 仅支持 android.graphics.SurfaceTexture 作为输出。 客户端可以使用 getExtensionSupportedSizes(..., Class) 查询重复请求输出支持的分辨率。
初始化至少需要一个用于重复的有效输出surface或一个用于在扩展配置参数的输出参数中注册的高质量单个请求的有效输出。 初始化最多将接受两个有效的输出surface,一个用于重复,另一个用于单个请求。 传递给 ExtensionSessionConfiguration 的其他不受支持的表面将导致抛出 IllegalArgumentException。
*/
public void createExtensionSession(
        @NonNull ExtensionSessionConfiguration extensionConfiguration)
        throws CameraAccessException {
    throw new UnsupportedOperationException("No default implementation");
}

/**

为来自 {@link TotalCaptureResult} 的一个新重新处理 {@link CaptureRequest} 创建一个 {@link CaptureRequest.Builder}。

@param inputResult 输出图像的捕获结果或用于生成此捕获请求的重新处理输入图像的输出图像之一。
@throws IllegalArgumentException 如果 inputResult 为 null
@throws CameraAccessException 如果相机设备不再连接或遇到致命错误
@throws IllegalStateException  如果相机设备已关闭

*/

@NonNull
public abstract CaptureRequest.Builder createReprocessCaptureRequest(
        @NonNull TotalCaptureResult inputResult) throws CameraAccessException;
/**
获取当前应用的全局摄像头音频限制模式。
应用程序可以使用此方法检索 setCameraAudioRestriction 中描述的系统范围的摄像头音频限制设置。
Return:
当前有效的系统范围静音模式设置
Throws:
CameraAccessException – 如果相机设备不再连接或遇到致命错误
IllegalStateException – 如果相机设备已关闭
*/
public @CAMERA_AUDIO_RESTRICTION int getCameraAudioRestriction() throws CameraAccessException {
    throw new UnsupportedOperationException("Subclasses must override this method");
}

/**

设置使用该CameraDevice时的音频限制模式。
某些相机硬件(例如支持光学图像稳定的设备)对设备振动敏感,并且视频录制可能会被意外的声音破坏。 应用程序可以使用此方法来抑制来自铃声、警报或通知的振动或声音。 其他振动或声音(例如媒体播放或可访问性)不会被静音。
静音模式是系统范围的设置。 当多个CameraDevice对象设置不同的模式时,系统会选择一个CameraDevice设置的所有模式的并集。 应用程序还可以使用 getCameraAudioRestriction 来查询当前有效的系统范围相机静音模式。
当 CameraDevice 关闭或应用程序与相机断开连接时,此 CameraDevice 的静音设置将自动删除。
Params:
mode – 选择此相机设备的音频限制模式的枚举。
Throws:
IllegalArgumentException – 如果不支持该模式
CameraAccessException – 如果相机设备不再连接或遇到致命错误
IllegalStateException – 如果相机设备已关闭

*/

public void setCameraAudioRestriction(
        @CAMERA_AUDIO_RESTRICTION int mode) throws CameraAccessException {
    throw new UnsupportedOperationException("Subclasses must override this method");
}

/**

检查相机设备是否支持特定的{@link SessionConfiguration}。

此方法对给定的{@link SessionConfiguration}执行运行时检查。 结果确认是否可以使用传递的会话配置成功地使用 {@link CameraDevice#createCaptureSession(
  android.hardware.camera2.params.SessionConfiguration)}。

该方法可以在活动捕获会话之前、期间和之后的任何时间点调用。 它不得以任何方式影响正常的相机行为,并且必须比创建常规或受限捕获会话快得多。

尽管此方法比创建新的捕获会话更快,但它并不旨在用于探索支持的流组合的整个空间。 可用的强制流组合
  {@link android.hardware.camera2.params.MandatoryStreamCombination} 更适合此目的。

请注意,会话参数将被忽略,并且不需要调用 {@link SessionConfiguration#setSessionParameters}。

@return 如果相机设备支持给定的会话配置,则返回{true},否则返回{false}。

@throw UnsupportedOperationException 如果相机设备不支持查询操作
@throw IllegalArgumentException 如果会话配置无效
@CameraAccessException 如果相机设备不再连接或遇到致命错误
@IllegalStateException 如果相机设备已关闭

*/
public boolean isSessionConfigurationSupported( @NonNull SessionConfiguration sessionConfig) throws CameraAccessException { throw new UnsupportedOperationException("Subclasses must override this method"); }

/**
尽快关闭与该相机设备的连接。
在此调用之后,对相机设备或活动会话接口的所有调用都将立即抛出 IllegalStateException,但对 close() 的调用除外。 一旦设备完全关闭,CameraDevice.StateCallback.onClosed 回调将被调用,并且相机可以自由地重新打开。
在此调用之后,除了最终的 CameraDevice.StateCallback.onClosed 调用之外,不会发生来自设备或活动会话的进一步回调,并且任何剩余的已提交捕获请求都将被丢弃,就像已调用 CameraCaptureSession.abortCaptures 一样,除非没有成功或者失败的回调被调用。

相机不再使用以后需要关闭,否则会一直占用相机资源,使得其他使用相机的应用无法使用。关闭相机比较合适的时机是在Activity的onPause()方法中。
*/

public abstract void close();

三、内部类StateCallback 

1、概述

StateCallback 用于接收有关相机设备状态更新的回调对象。必须向 {@link CameraManager#openCamera} 方法提供回调实例才能打开相机设备。

这些状态更新包括有关设备完成启动的通知(允许调用 {@link #createCaptureSession})、有关设备断开连接或关闭的通知以及有关意外设备错误的通知。

有关特定 {@link CaptureRequest CaptureRequests} 进度的事件通过提供给 {@link CameraCaptureSession#capture}、{@link CameraCaptureSession#captureBurst} 的 {@link CameraCaptureSession.CaptureCallback} 提供,
  {@link CameraCaptureSession#setRepeatingRequest},或
  {@link CameraCaptureSession#setRepeatingBurst} 方法。

2、常量

/**
onError 可以报告一个错误代码,表明相机设备已在使用中。
由于相机被更高优先级的相机 API 客户端使用而导致打开相机失败时,可能会产生此错误。
可以参看:onError 
*/
public static final int ERROR_CAMERA_IN_USE = 1;

/**

onError 可以报告的错误代码,指示无法打开相机设备,因为有太多其他打开的相机设备。
已达到系统范围内打开摄像头数量的限制,在关闭之前的实例之前,无法打开更多摄像头设备。
打开相机失败时会产生此错误。
可以参看:onError

*/

public static final int ERROR_MAX_CAMERAS_IN_USE = 2;
/**
onError 可以报告的错误代码,指示由于设备策略而无法打开相机设备。
可以参看:
android.app.admin.DevicePolicyManager.setCameraDisabled(android.content.ComponentName, boolean), onError

*/
public static final int ERROR_CAMERA_DISABLED = 3;

/**

onError 可以报告的错误代码,指示相机设备遇到致命错误。
摄像头设备需要重新打开才能再次使用。
可以参看:onError

*/

public static final int ERROR_CAMERA_DEVICE = 4;

/**

onError 可以报告的错误代码,指示相机服务遇到致命错误。
Android 设备可能需要关闭并重新启动才能恢复相机功能,或者可能存在持续的硬件问题。
可以通过关闭 CameraDevice 和 CameraManager 并尝试从头开始再次获取所有资源来尝试恢复。
可以参看:onError

*/

public static final int ERROR_CAMERA_SERVICE = 5;

3、方法

/**
当相机设备完成打开时调用的方法。
此时,相机设备就可以使用了,并且可以调用 {@link CameraDevice#createCaptureSession} 来设置第一个捕获会话。
@param camera 已打开的相机设备
*/
public abstract void onOpened(@NonNull CameraDevice camera); // 必须实现

/**

当相机设备已通过 close 关闭时调用的方法。
将来任何尝试调用此 CameraDevice 上的方法都将抛出 IllegalStateException。
此方法的默认实现不执行任何操作。
参数:
@param camera– 已关闭的相机设备

*/

public void onClosed(@NonNull CameraDevice camera) {
    // Default empty implementation
}

/**

当相机设备不再可用时调用的方法。
如果打开相机失败,可能会调用此回调而不是 onOpened。
任何尝试调用此 CameraDevice 上的方法都将抛出 CameraAccessException。 断开连接可能是由于安全策略或权限的更改所致; 可移动摄像头设备的物理断开; 或者更高优先级的相机 API 客户端需要相机。
调用此方法后可能仍然会调用捕获回调,或者传递到活动输出的新图像缓冲区。
默认实现将有关断开连接的通知记录到系统日志中。
发生这种情况后,您应该关闭相机来清理相机,因为只有再次打开相机才能恢复。 对于大多数用例,这将是相机再次可用的时候。
参数:
@param camera– 已断开连接的设备

*/

public abstract void onDisconnected(@NonNull CameraDevice camera); //必须实现

/**

当相机设备遇到严重错误时调用的方法。
如果打开相机失败,可能会调用此回调而不是 onOpened。
这表明相机设备或相机服务出现某种故障。 将来任何尝试调用此 CameraDevice 上的方法都将抛出 CameraAccessException 并带有 CAMERA_ERROR 原因。
收到此错误后,可能仍会调用捕获完成或相机流回调。
发生这种情况后,您应该关闭相机并清理干净。 进一步的恢复尝试是特定于错误代码的。
参数:
@param camera– 报告错误的设备

@param error – 错误代码。

*/

public abstract void onError(@NonNull CameraDevice camera, @ErrorCode int error); // 必须实现

猜你喜欢

转载自blog.csdn.net/github_27263697/article/details/131444567