Android P CameraCaptureSession

本文介绍CameraCaptureSession类,它是Android相机API的一部分,用于配置和控制从相机设备捕获图像的过程。文章详细解释了如何创建、配置和管理捕获会话,以及如何提交各种类型的捕获请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CameraCaptureSession

public abstract class CameraCaptureSession extends Object implements AutoCloseable

一个已配置好的CameraDevice的捕获会话,用于从相机捕获图像或重新处理先前在同一会话中从相机捕获的图像。

CameraCaptureSession的创建时通过提供一组目标输出Surface给CameraDevice#createCaptureSession方法,或者提供一个InputConfiguration和一组目标输出Surface给CameraDevice#createReprocessableCaptureSession方法,第二种方法用于可重新处理的捕获会话。创建后,会话处于活动状态,直到摄像机设备创建新会话或关闭摄像机设备。

所有捕获会话都可用于从摄像机捕获图像,但只有可重新处理的捕获会话可以重新处理先前在同一会话中从摄像机捕获的图像。

创建会话是一项费时的操作,可能需要几百毫秒,因为它需要配置摄像机设备的内部管道并分配内存缓冲区以将图像发送到所需目标。因此,设置是异步完成的,CameraDevice#createCaptureSession和CameraDevice#createReprocessableCaptureSession会发送会话可用的消息到侦听器CameraCaptureSession.StateCallback#onConfigured回调。如果无法完成配置,则调用CameraCaptureSession.StateCallback #onConfigureFailed,并且session不会变为活动状态。

如果摄像机设备创建了新会话,则会关闭先前的会话,并将调用其关联的StateCallback#onClosed回调。 如果在会话关闭后调用,则所有会话方法都将抛出IllegalStateException。

关闭会话会清除所有重复请求(就像调用了stopRepeating()一样),但在新创建的会话接管并重新配置摄像头设备之前,仍将正常完成所有正在进行的捕获请求。

 

内部类

  • CameraCaptureSession.CaptureCallback
  • CameraCaptureSession.StateCallback

 

公共方法

  • abortCaptures
public abstract void abortCaptures ()

尽可能快地丢弃当前待处理和正在进行的所有捕获。

相机设备将尽可能快地丢弃其所有当前工作。 一些正在进行的捕获可以成功完成并调用CaptureCallback#onCaptureCompleted,而其他捕获将触发CaptureCallback#onCaptureFailed回调。 如果设置了重复请求或重复突发,则将其清除。

此方法是使用CameraDevice #creinCaptureSession或CameraDevice#createReprocessableCaptureSession将摄像机设备切换到新会话的最快方法,代价是丢弃正在进行的工作。必须在创建新会话之前调用它。一旦所有挂起的请求都完成或丢弃,如果会话尚未关闭,将调用StateCallback#onReady回调。 否则,当摄像机设备创建新会话时,将触发StateCallback#onClosed回调。

取消将至少在来自摄像机设备的数据流中引入短暂暂停,因为一旦摄像机设备被清空,第一个新请求必须在产生新的输出缓冲器之前通过整个摄像机管道。

这意味着不建议使用abortCaptures()来简单地删除待处理的请求; 它最适合用于快速切换输出配置,或用于取消长时间进行中的请求(例如多秒捕获)。

  • capture
public abstract int capture (CaptureRequest request, 
                CameraCaptureSession.CaptureCallback listener, 
                Handler handler)

提交要由相机设备捕获的图像的请求。

该请求定义了捕获单个图像的所有参数,包括传感器,镜头,闪光灯和后处理设置。

每个请求将生成一个CaptureResult并为一个或多个目标Surface生成新帧,使用CaptureRequest构建器的CaptureRequest.Builder#addTarget方法设置。 目标Surface(使用CaptureRequest.Builder#addTarget设置)必须是创建此捕获session时提供的Surface的子集。

可以同时进行多个常规和重新处理请求。 如果单独进行常规请求或重新处理请求,则会按先进先出顺序处理它们。 如果同时进行常规请求和重新处理请求,则以先进先出顺序处理常规请求,并分别按先进先出顺序处理重新处理请求。 但是,未指定常规请求和正在进行的重新处理请求的处理顺序。 换句话说,常规请求将始终在稍后提交的常规请求之前处理。 在稍后提交的重新处理请求之前,将始终处理重新处理请求。 但是,在稍后提交的重新处理请求之前,可能无法处理常规请求。

通过此方法提交的请求具有比通过setRepeatingRequest(CaptureRequest,CameraCaptureSession.CaptureCallback,Handler)或setRepeatingBurst(List,CameraCaptureSession.CaptureCallback,Handler)提交的请求更高的优先级,并且将在当前repeat / repeatBurst处理完成后立即处理。

所有捕获会话都可用于从摄像头捕获图像,但只有被CameraDevice#createReprocessableCaptureSession创建的会话可以提交重新处理捕获请求。 向常规捕获会话提交重新处理请求将导致IllegalArgumentException。

  • captureBurst
public abstract int captureBurst (List<CaptureRequest> requests, 
                CameraCaptureSession.CaptureCallback listener, 
                Handler handler)

提交要按顺序捕获的请求列表作为Burst。 将在尽可能少的时间内捕获Burst,并且不会与其他捕获或重复呼叫提交的请求交错。

常规和重新处理请求可以在一次Burst中混合在一起。 将分别按顺序捕获常规请求和重新处理请求。 但是,未指定常规请求和重新处理请求之间的处理顺序。 每次捕获都会为一个或多个目标Surface生成一个CaptureResult和图像缓冲区。 目标Surface(使用CaptureRequest.Builder#addTarget设置)必须是创建此捕获会话时提供的Surface的子集。

这种方法与简单地重复调用capture(CaptureRequest,CameraCaptureSession.CaptureCallback,Handler)之间的主要区别在于,此方法保证不会有其他请求穿插在突发中。

所有捕获会话都可用于从摄像头捕获图像,但只有CameraDevice#createReprocessableCaptureSession创建的会话可以提交重新处理捕获请求。 向常规捕获会话提交重新处理请求将导致IllegalArgumentException。

  • captureBurstRequests
public int captureBurstRequests (List<CaptureRequest> requests, 
                Executor executor, 
                CameraCaptureSession.CaptureCallback listener)

提交要按顺序捕获的请求列表作为Burst。 将在尽可能少的时间内捕获Burst,并且不会与其他捕获或重复呼叫提交的请求交错。

此方法的行为与captureBurst(java.util.List,android.hardware.camera2.CameraCaptureSession.CaptureCallback,android.os.Handler)的行为相匹配,除了它使用Executor作为参数而不是Handler。

  • captureSingleRequest
public int captureSingleRequest (CaptureRequest request, 
                Executor executor, 
                CameraCaptureSession.CaptureCallback listener)

提交要由相机设备捕获的图像的请求。

此方法的行为与capture(android.hardware.camera2.CaptureRequest,android.hardware.camera2.CameraCaptureSession.CaptureCallback,android.os.Handler)的行为相匹配,除了它使用Executor作为参数而不是Handler。

  • close
public abstract void close ()

异步关闭此捕获会话。

关闭会话将释放会话的目标输出Surface,以便与新会话或可以绘制到Surface的其他API一起重用。

请注意,使用CameraDevice#createCaptureSession创建新的捕获会话将自动关闭任何现有的捕获会话,并调用较旧的会话侦听器的StateCallback#onClosed回调。 直接使用CameraDevice#createCaptureSession而不关闭是快速切换到新会话的推荐方法,因为可以更有效地重用未更改的目标输出。

一旦会话关闭,其上的所有方法都将抛出IllegalStateException,并且任何重复的请求或突发都将被停止(就像调用了stopRepeating())。 但是,提交给会议的任何正在进行的捕获请求将照常完成; 一旦所有捕获都已完成并且会话已被拆除,将调用StateCallback#onClosed。

结束会话是幂等的; 关闭不止一次没有效果。

  • finalizeOutputConfigurations
public abstract void finalizeOutputConfigurations (List<OutputConfiguration> outputConfigs)

最终确定现在包含延迟和/或额外Surfaces的输出配。

对于需要配置预览和其他输出配置的相机使用情况,预览Surface可能需要一些时间才能准备好。 例如,如果从SurfaceView获取预览Surface,则只有在UI布局完成后,SurfaceView才会准备好,这可能会延迟相机启动。

为了加快相机启动时间,应用程序可以将CameraCaptureSession配置为最终预览大小(通过OutputConfiguration#OutputConfiguration(Size,Class)),并将预览输出配置推迟到Surface准备就绪。 使用此延迟输出和其他正常输出成功创建CameraCaptureSession后,只要不包含延迟输出Surface,应用程序就可以开始提交请求。 一旦延迟Surface准备就绪,应用程序可以使用OutputConfiguration#addSurface方法将Surface添加到延迟输出配置,然后通过此方法更新延迟输出配置,然后才能使用此输出目标提交捕获请求。

如果多个Surface共享相同的OutputConfiguration,并且其中一个Surface在创建CameraCaptureSession后变为可用,则也可以调用此函数。 在这种情况下,应用程序必须首先使用可用的Surface创建OutputConfiguration,然后在创建CameraCaptureSession之前通过OutputConfiguration #enableSurfaceSharing启用进一步的Surface共享。 创建CameraCaptureSession后,一旦额外的Surface可用,应用程序必须在使用此方法完成配置之前调用OutputConfiguration#addSurface。

如果提供的OutputConfigurations在创建会话时保持不变,则此函数调用无效。 只能为特定输出配置调用此函数一次。

此调用返回后,此OutputConfiguration列表中包含的输出Surface可用作CaptureRequest目标。

CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY级设备不支持此方法。

  • getDevice

public abstract CameraDevice getDevice ()

获取创建此会话的摄像头设备。

  • getInputSurface
public abstract Surface getInputSurface ()

获取与可重新处理的捕获会话关联的输入Surface。

每个可重新处理的捕获会话都有一个输入Surface,重新处理捕获请求从这个Surface获取输入图像而不是摄像头设备。 应用程序可以使用此输入Surface创建ImageWriter,并使用它为重新处理捕获请求提供输入图像。 当可重新处理的捕获会话关闭时,输入Surface将被放弃并变为无效。

  • isReprocessable
public abstract boolean isReprocessable ()

如果应用程序可以使用此摄像头捕获会话提交重新处理捕获请求,则返回TRUE。

  • prepare
public abstract void prepare (Surface surface)

为输出Surface预分配所有缓冲区。

通常,按需分配给定输出Surface的映像缓冲区,以最小化启动延迟和内存开销。

但是,在某些情况下,可能需要在将任何以Surface为目标的请求实际提交给设备之前分配缓冲区。 大缓冲区可能需要一些时间来分配,这可能导致提交请求的延迟,直到分配足够的缓冲区以达到稳态行为。 此类延迟可能导致Bursts花费的时间超过预期,或导致预览输出中的跳跃或断断续续。

prepare()方法可用于执行此预分配。 只有在将Surface用作请求的目标之前,才可以为给定的输出Surface调用它。 分配的缓冲区数量是提供输出Surface的消费者所需的计数总和,以及摄像机设备填充其管道所需的最大数量。 由于这可能比稳态操作实际需要的数量更多,因此使用prepare可能会导致比正常按需行为导致更高的内存消耗。Prepare()也会延迟首次输出到给定的Surface,一旦分配完成,换取更平滑的帧速率。

例如,创建一个maxImages参数为10但仅同时使用3个同时图像的ImageReader的应用程序通常只会分配这3个图像(加上相机设备所需的平滑操作)。 但是在ImageReader Surface上使用prepare()将导致分配所有10个图像。 因此,使用此方法的应用程序应注意仅请求其应用程序实际所需的缓冲区数。

如果在连续会话中使用相同的输出Surface(不显式关闭第一个会话),则其已分配的缓冲区将被转移,如果在第一个会话中将其用作捕获请求的目标,则无法在第二个会话上调用prepare 。

分配完成后,将使用提供给此方法的Surface调用StateCallback#onSurfacePrepared。 在prepare调用和onSurfacePrepared调用之间,提供给prepare的Surface不得用作提交给此会话的CaptureRequest的目标。

请注意,如果2个Surface通过OutputConfiguration #enableSurfaceSharing和OutputConfiguration#addSurface共享相同的流,则只需要在一个、Surface上调用prepare(),并且将为两个Surface触发{link StateCallback#onSurfacePrepared}。

LEGACY设备无法预先分配输出缓冲区; 对于这些设备,将立即调用StateCallback#onSurfacePrepared,并且不会进行预分配。

  • setRepeatingBurst
public abstract int setRepeatingBurst (List<CaptureRequest> requests, 
                CameraCaptureSession.CaptureCallback listener, 
                Handler handler)

请求通过此捕获会话无休止地重复捕获一系列图像。

使用此方法,摄像机设备将以尽可能最大的速率连续捕获图像,循环显示所提供的CaptureRequest列表中的设置。

如果通过捕获(CaptureRequest,CameraCaptureSession.CaptureCallback,Handler)或captureBurst(List,CameraCaptureSession.CaptureCallback,Handler)提交请求,则在处理更高优先级的请求之前,将完成请求列表的当前重复。 这可以保证应用程序始终接收在最短时间内捕获的完整重复Burst,而不是与更高优先级捕获交错的Burst或不完整捕获。

重复Burst请求是应用程序维护预览或其他连续帧流的简单方法,其中每个请求以可预测的方式不同,而不必通过captureBurst(List,CameraCaptureSession.CaptureCallback,Handler)连续提交请求。

要停止重复捕获,请调用stopRepeating()。 然而,任何正在进行的Burst仍将完成。 调用abortCaptures()也会清除请求。

调用此方法将替换此方法设置的先前设置的重复请求或Burst或setRepeatingRequest(CaptureRequest,CameraCaptureSession.CaptureCallback,Handler),尽管在使用新的重复Burst之前将完成任何正在进行的Burst。

此方法不支持重新处理捕获请求,因为必须从与要重新处理的输入图像匹配的TotalCaptureResult创建每个重新处理CaptureRequest。 这是为了重新处理而发送的捕获的TotalCaptureResult,或者是一组捕获的TotalCaptureResult之一,当整个集合的数据由应用程序组合成单个重新处理输入图像时。 请求必须是从相机捕获图像。 如果提交了重新处理捕获请求,则此方法将抛出IllegalArgumentException。

  • setRepeatingBurstRequests
public int setRepeatingBurstRequests (List<CaptureRequest> requests, 
                Executor executor, 
                CameraCaptureSession.CaptureCallback listener)

请求通过此捕获会话无休止地重复捕获一系列图像。

此方法的行为与setRepeatingBurst(java.util.List,android.hardware.camera2.CameraCaptureSession.CaptureCallback,android.os.Handler)的行为相匹配,除了它使用Executor作为参数而不是Handler。

  • setRepeatingRequest
public abstract int setRepeatingRequest (CaptureRequest request, 
                CameraCaptureSession.CaptureCallback listener, 
                Handler handler)

请求通过此捕获会话无休止地重复捕获图像。

使用此方法,相机设备将使用所提供的CaptureRequest中的设置以最大可能的速率连续捕获图像。

重复请求是应用程序维护预览或其他连续帧流的简单方法,无需通过捕获(CaptureRequest,CameraCaptureSession.CaptureCallback,Handler)连续提交相同的请求。

重复请求的优先级低于通过捕获(CaptureRequest,CameraCaptureSession.CaptureCallback,Handler)或captureBurst(List,CameraCaptureSession.CaptureCallback,Handler)提交的请求,因此如果重复请求是在捕获(CaptureRequest,CameraCaptureSession.CaptureCallback,Handler)时 激活后,将在处理任何进一步的重复请求之前处理捕获请求。

要停止重复捕获,请调用stopRepeating()。 调用abortCaptures()也会清除请求。

调用此方法将替换此方法或setRepeatingBurst(List,CameraCaptureSession.CaptureCallback,Handler)设置的任何早期重复请求或Burst,尽管在使用新的重复请求之前将完成任何正在进行的Burst。

此方法不支持重新处理捕获请求,因为必须从与要重新处理的输入图像匹配的TotalCaptureResult创建每个重新处理CaptureRequest。 这是为了重新处理而发送的捕获的TotalCaptureResult,或者是一组捕获的TotalCaptureResult之一,当整个集合的数据由应用程序组合成单个重新处理输入图像时。 请求必须是从相机捕获图像。 如果提交了重新处理捕获请求,则此方法将抛出IllegalArgumentException。

  • setSingleRepeatingRequest
public int setSingleRepeatingRequest (CaptureRequest request, 
                Executor executor, 
                CameraCaptureSession.CaptureCallback listener)

请求通过此捕获会话无休止地重复捕获图像。

此方法的行为与setRepeatingRequest(android.hardware.camera2.CaptureRequest,android.hardware.camera2.CameraCaptureSession.CaptureCallback,android.os.Handler)的行为相匹配,除了它使用Executor作为参数而不是Handler。

  • stopRepeating
public abstract void stopRepeating ()

通过setRepeatingRequest或setRepeatingBurst(List,CameraCaptureSession.CaptureCallback,Handler)取消任何正在进行的重复捕获集。 对通过capture或captureBurst提交的请求没有影响。

任何当前正在进行的捕获仍将完成,捕获中期的任何Burst也将完成。 要确保设备已完成处理其所有捕获请求并处于就绪状态,请在调用此方法后等待StateCallback#onReady回调。

  • updateOutputConfiguration
public void updateOutputConfiguration (OutputConfiguration config)

配置完成后更新OutputConfiguration,请参阅finalizeOutputConfigurations(List)。

必须更新通过调用OutputConfiguration#addSurface或OutputConfiguration #removeSurface修改的任何OutputConfiguration。 在更新调用返回而不抛出异常之后,可以在后续捕获请求中引用任何新添加的Surface。

被移除的Surface不得是任何活动重复或单个/Burst请求的一部分,或具有任何未决结果。 考虑首先通过setRepeatingRequest(CaptureRequest,CameraCaptureSession.CaptureCallback,Handler)或setRepeatingBurst(List,CameraCaptureSession.CaptureCallback,Handler)更新任何重复请求,然后在序列完成CaptureCallback#onCaptureSequenceCompleted之前等待最后一个帧编号,然后再调用updateOutputConfiguration删除以前的 活动Surface。

添加的Surface不得是任何其他已注册的OutputConfiguration的一部分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值