Android --camera2(CameraCaptureSession)

3,888 阅读26分钟

CameraCaptureSession

通过CameraDevicecreateCaptureSession创建,在CameraCaptureSession.StateCallbackonConfigured回调方法中得到CameraCaptureSession实例,之后就可以调用setRepeatingRequest来预览或录像或捕获每一帧数据,也可以调用 capture来拍照或捕获单帧数据。
为CameraDevice配置的捕获会话, 用于从相机捕获图像或重新处理先前在同一会话中从相机捕获的图像。
CameraCaptureSession 是通过 createCaptureSession,  InputConfigurationcreateReprocessableCaptureSession创建的。创建后,会话一直处于活动状态,直到相机设备创建新会话或关闭相机设备。
创建会话是一项耗时的操作,可能需要数百毫秒,因为它需要配置相机设备的内部管道并分配内存缓冲区以将图像发送到所需的目标。因此,设置是异步完成的,createCaptureSession和 createReprocessableCaptureSession将发送可用的CameraCaptureSession到提供监听器的 onConfigured回调。如果无法完成配置,则 onConfigureFailed调用 ,并且会话不会变为活动状态。
如果摄像头设备创建了一个新会话,则关闭前一个会话,并调用onClosed。如果在会话关闭后调用,所有会话方法都将抛出 IllegalStateException。
关闭的会话会清除任何重复的请求(就像stopRepeating()已被调用一样),在新创建的会话接管并重新配置相机设备之前,但仍将正常完成所有正在进行的捕获请求。

中止捕获

public abstract void abortCaptures ()

尽快丢弃所有当前待办和正在进行的捕获。
相机设备将尽快放弃其所有当前工作。一些飞行中的捕获可能会成功完成并调用CaptureCallback#onCaptureCompleted,而其他的会触发CaptureCallback#onCaptureFailed回调。如果设置了重复请求或重复突发,将被清除。
此方法是使用CameraDevice#createCaptureSession或 CameraDevice#createReprocessableCaptureSession 将相机设备切换到新会话的最快方法,代价是丢弃正在进行的工作。必须在创建新会话之前调用它。一旦所有挂起的请求完成或丢弃,如果会话尚未关闭,StateCallback#onReady回调将被调用。否则,StateCallback#onClosed 当相机设备创建新会话时将触发回调。
取消将在来自相机设备的数据流中引入至少短暂的暂停,因为一旦相机设备被清空,第一个新请求必须在产生新的输出缓冲区之前通过整个相机管道。
这意味着不建议使用abortCaptures()简单地删除挂起的请求;它最适合用于快速切换输出配置,或取消正在进行的长时间请求(例如多秒捕获)

捕获

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

提交由相机设备捕获的图像的请求。
该请求定义了用于捕获单个图像的所有参数,包括传感器、镜头、闪光灯和后处理设置。
每个请求将生成一个CaptureResult和为一个或多个目标 Surface 生成新帧,使用 CaptureRequest.Builder#addTarget方法进行设置。目标Surface必须是创建此捕获会话时提供的Surface的子集。
可以同时进行多个常规和重新处理请求。如果只有常规请求或正在处理的重新处理请求,它们将按照先进先出的顺序进行处理。如果常规请求和重新处理请求都在进行中,则分别按照先进先出的顺序处理常规请求,并分别按照先进先出的顺序处理重新处理请求。但是,未指定常规请求和进行中的重新处理请求的处理顺序。换句话说,常规请求将始终在稍后提交的常规请求之前处理。重新处理请求将始终在稍后提交的重新处理请求之前进行处理。但是,在重新处理稍后提交的请求之前,可能无法处理常规请求。
通过此方法capture提交的请求比通过setRepeatingRequest(CaptureRequest, CameraCaptureSession.CaptureCallback, Handler)或 setRepeatingBurst(List, CameraCaptureSession.CaptureCallback, Handler)提交的请求具有更高的优先级,并且将在当前的 repeat/repeatBurst 处理完成后立即处理。
所有捕获会话都可用于从相机捕获图像,但只有通过 createReprocessableCaptureSession创建的捕获会话 才能提交重新处理捕获请求。向常规捕获会话提交重新处理请求将导致IllegalArgumentException.

捕捉突发

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

提交要作为突发按顺序捕获的请求列表。突发将在尽可能短的时间内被捕获,并且不会与其他捕获或重复调用提交的请求交错。
此方法与简单capture(CaptureRequest, CameraCaptureSession.CaptureCallback, Handler)重复调用的主要区别在于 ,此方法可保证不会在突发中穿插其他请求。

捕获突发请求

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

提交要作为突发按顺序捕获的请求列表。突发将在尽可能短的时间内被捕获,并且不会与其他捕获或重复调用提交的请求交错。
此方法的行为与 captureBurst(java.util.List, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) 的行为相匹配,不同之处在于它Executor用作参数而不是Handler

捕获单个请求

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。\

关闭

public abstract void close ()

异步关闭此捕获会话。
关闭会话会释放会话的目标输出 Surfaces,以供新会话或可绘制到 Surfaces 的其他 API 重用。
请注意,对于创建新会话或关闭相机设备等常见使用场景,直接调用相应的 API 会更快,而无需调用此方法。close ()仅在应用程序想要取消配置相机但保持设备打开以备后用时有用。
创建一个新的捕获会话CameraDevice#createCaptureSession 将自动关闭任何现有的捕获会话,并调用旧会话侦听器的 StateCallback#onClosed回调。CameraDevice#createCaptureSession 直接使用而不关闭是快速切换到新会话的推荐方法,因为可以更有效地重用未更改的目标输出。
建议使用CameraDevice#close快速关闭相机,不调用此 API。
一旦会话关闭,其上的所有方法都会抛出 IllegalStateException,并且任何重复的请求或突发都将停止(就像stopRepeating()被调用一样)。但是,任何提交给会话的正在进行的捕获请求都将正常完成;一旦所有捕获完成并且会话被拆除, StateCallback#onClosed将被调用。
关闭会话是幂等的;多次关闭没有效果。

完成输出配置

public abstract void finalizeOutputConfigurations (List<OutputConfiguration> outputConfigs)

完成现在包含延迟和/或额外表面的输出配置。
对于需要配置预览和其他输出配置的相机用例,预览 Surface 可能需要一些时间才能准备好。例如,如果从SurfaceView中获取预览 Surface,则 SurfaceView 将仅在 UI 布局完成后准备就绪,可能会延迟相机启动。
为了加快相机启动时间,应用程序可以配置 CameraCaptureSession最终的预览大小(通过 a deferred OutputConfiguration),并将预览输出配置推迟到 Surface 准备好。CameraCaptureSession使用此延迟输出和其他正常输出成功创建后 ,应用程序可以开始提交请求,只要它们不包含延迟输出 Surfaces。一旦延迟 Surface 准备就绪,应用程序可以使用该OutputConfiguration#addSurface方法将 Surface 添加到延迟输出配置中 ,然后通过该方法更新延迟输出配置,然后才能使用该输出目标提交捕获请求。
如果多个曲面共享相同的 OutputConfiguration,并且其中一个曲面在CameraCaptureSession创建后可用,也可以调用此函数。在这种情况下,应用程序必须首先使用可用的 Surface 创建 OutputConfiguration,然后OutputConfiguration#enableSurfaceSharing在创建 CameraCaptureSession 之前通过 启用进一步的 Surface 共享 。创建 CameraCaptureSession 后,一旦额外的 Surface 可用,应用程序必须OutputConfiguration#addSurface在使用此方法完成配置之前调用。
如果提供的 OutputConfigurations 在会话创建时没有改变,则此函数调用无效。对于特定的输出配置,此函数只能调用一次。
此调用返回后,此OutputConfigurations列表中包含的输出 Surface 可用作CaptureRequest目标。
LEGACY级设备不支持此方法 。

获取设备

public abstract CameraDevice getDevice ()

获取为此会话创建的相机设备

获取输入表面

public abstract Surface getInputSurface ()

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

可再加工

public abstract boolean isReprocessable ()

返回应用程序是否可以使用此相机捕获会话提交重新处理捕获请求。

准备

public abstract void prepare (Surface surface)

为输出 Surface 预先分配所有缓冲区。
通常,给定输出 Surface 的图像缓冲区是按需分配的,以最大限度地减少启动延迟和内存开销。
但是,在某些情况下,可能需要在针对 Surface 的任何请求实际提交给设备之前分配缓冲区。大缓冲区可能需要一些时间来分配,这可能会导致提交请求的延迟,直到分配足够的缓冲区以达到稳态行为。此类延迟可能会导致突发所需的时间比预期的要长,或者导致预览输出中出现跳过或断断续续的情况。
prepare() 方法可用于执行此预分配。只能在给定的输出 Surface 用作请求目标之前调用它。分配的缓冲区数是消费者提供输出 Surface 所需的计数与相机设备填充其管道所需的最大数量之和。由于这可能比稳态操作实际所需的数字更大,因此使用 prepare 可能会导致比正常的按需行为导致更高的内存消耗。 Prepare() 还将延迟第一次输出到给定的时间Surface,在分配完成后换取更平滑的帧率。
例如,创建ImageReader一个 maxImages 参数为 10,但一次仅使用 3 个同时图像的应用程序 通常只会导致分配这 3 个图像(加上相机设备平滑操作所需的内容)。但是在 ImageReader Surface 上使用 prepare() 将导致分配所有 10 个图像。因此,使用此方法的应用程序应注意仅请求其应用程序实际所需的缓冲区数量。
如果在连续会话中使用相同的输出 Surface(没有明确关闭第一个会话),那么它已经分配的缓冲区被结转,如果它被用作第一个会话中的捕获请求的目标,则不能在第二个会话上调用 prepare。

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

注意,如果两个表面通过OutputConfiguration.enableSurfaceSharing()OutputConfiguration#addSurface共享同一个流,prepare() 只需要在一个表面上调用,并且 {link StateCallback#onSurfacePrepared} 将在两个表面上被触发。

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

设置重复突发

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

请求通过此捕获会话无休止地重复捕获一系列图像。
使用此方法,相机设备将持续捕捉图像,CaptureRequests以可能的最大速率循环浏览提供的 列表中的设置 。
如果通过capture(CaptureRequest, CameraCaptureSession.CaptureCallback, Handler)captureBurst(List, CameraCaptureSession.CaptureCallback, Handler) 提交请求,则请求列表的当前重复将在处理更高优先级的请求之前完成。这保证了应用程序始终接收在最短的时间内捕获的完整重复突发,而不是与更高优先级的捕获或不完整的捕获交错的突发。\

重复突发请求是应用程序维护预览或其他连续帧流的一种简单方法,其中每个请求都以可预测的方式不同,而不必通过.captureBurst(List, CameraCaptureSession.CaptureCallback, Handler)
要停止重复捕获,请调用stopRepeating()。但是,任何正在进行的爆发仍将完成。调用 abortCaptures()也将清除请求。
调用此方法将替换先前设置的重复请求或由此方法设置的突发或突发setRepeatingRequest(CaptureRequest, CameraCaptureSession.CaptureCallback, Handler),尽管任何进行中的突发都将在使用新的重复突发之前完成。
此方法不支持重新处理捕获请求,因为每个重新处理都 CaptureRequest必须从TotalCaptureResult与要重新处理的输入图像匹配的 中创建。 当应用程序将整个集合中的数据组合成单个重新处理输入图像时TotalCaptureResult,这可以是发送用于重新处理的捕获,或者TotalCaptureResults是一组捕获中的一个。请求必须是从相机捕获图像。如果提交了重新处理捕获请求,此方法将抛出IllegalArgumentException。

设置重复突发请求

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

设置重复请求

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

请求通过此捕获会话无休止地重复捕获图像。
使用此方法,相机设备将使用CaptureRequest提供的设置以可能的最大速率连续捕获图像。
重复请求是应用程序维护预览或其他连续帧流的一种简单方式,而无需通过capture(CaptureRequest, CameraCaptureSession.CaptureCallback, Handler)不断提交特定请求
重复请求的优先级低于通过capture(CaptureRequest, CameraCaptureSession.CaptureCallback, Handler)captureBurst(List, CameraCaptureSession.CaptureCallback, Handler)capture(CaptureRequest, CameraCaptureSession.CaptureCallback, Handler)提交的请求,因此如果在重复请求处于活动状态时调用,捕获请求将在处理任何进一步的重复请求之前被处理。
要停止重复捕获,请调用stopRepeating()。调用 abortCaptures()也将清除请求。
调用此方法将替换任何通过此方法或setRepeatingBurst(List, CameraCaptureSession.CaptureCallback, Handler) 设置的较早的重复请求或突发,尽管任何进行中的突发都将在使用新的重复请求之前完成。
此方法不支持重新处理捕获请求,因为每个重新处理都 CaptureRequest必须从TotalCaptureResult与要重新处理的输入图像匹配的 中创建。 当应用程序将整个集合中的数据组合成单个重新处理输入图像时TotalCaptureResult,这可以是发送用于重新处理的捕获,或者TotalCaptureResults是一组捕获中的一个。请求必须是从相机捕获图像。如果提交了重新处理捕获请求,此方法将抛出 IllegalArgumentException。

设置单个重复请求

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

停止重复

public abstract void stopRepeating ()

取消由setRepeatingRequestsetRepeatingBurst(List, CameraCaptureSession.CaptureCallback, Handler)设置的任何正在进行的重复捕获 。对通过capturecaptureBurst提交的请求没有影响 。
任何当前飞行中的捕获仍将完成,任何在捕获过程中的突发也将完成。为确保设备已完成处理其所有捕获请求并处于就绪状态,请在StateCallback#onReady回调后调用此方法。

支持离线处理

public boolean supportsOfflineProcessing (Surface surface)

查询给定的 Surface 是否能够支持离线模式。
支持离线模式的表面可以作为参数传递给 switchToOffline(Collection, Executor, CameraOfflineSession.CameraOfflineSessionCallback)

切换到离线

public CameraOfflineSession switchToOffline (Collection<Surface> offlineSurfaces, Executor executor, CameraOfflineSession.CameraOfflineSessionCallback listener)

将当前捕获会话和一组给定的注册相机表面切换到离线处理模式。
设备支持此方法将显示 OFFLINE_PROCESSING 能力在CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES。如果支持此方法,应用程序可以使用它来改善关闭相机或重新创建捕获会话的延迟,而不会丢失正在进行的捕获请求输出。
离线处理模式和相应的CameraOfflineSession在几个方面不同于常规在线相机捕获会话。成功的离线切换将关闭当前活动的相机捕获会话。相机客户端也可以在所选捕获请求的离线处理仍在进行中时调用CameraDevice#close。这种无副作用的设备关闭只有在离线会话移动到就绪状态时才有可能。一旦发生这种情况,关闭相机设备将不会影响挂起的离线请求,它们必须正常完成。
离线处理模式切换可能需要数百毫秒才能完成,因为底层相机实现必须中止所有当前活动的重复请求以及客户端未指定的所有其他待处理请求。此外,在离线会话中继续处理的所有请求从相机传感器获取其初始输入帧之前,将阻止切换。对switchToOffline(Collection, Executor, CameraOfflineSession.CameraOfflineSessionCallback)自身的调用不会阻塞,只会触发离线切换序列。一旦整个序列完成,客户将收到CameraOfflineSessionCallback#onReady通知。
请注意,成功调用此方法后,当前活动的捕获会话将不再有效,客户端将开始接收捕获回调,并将相应的CameraOfflineSession作为会话参数传递。

更新输出配置

public void updateOutputConfiguration (OutputConfiguration config)

OutputConfiguration配置完成后更新见 finalizeOutputConfigurations(List)
任何OutputConfiguration已通过调用 OutputConfiguration#addSurfaceOutputConfiguration#removeSurface修改的内容,必须更新。在更新调用返回后没有抛出异常,任何新添加的表面都可以在后续的捕获请求中被引用。\

被移除的表面不得属于任何活动的重复或单一/突发请求或具有任何未决结果。考虑首先通过setRepeatingRequest(CaptureRequest, CameraCaptureSession.CaptureCallback, Handler)setRepeatingBurst(List, CameraCaptureSession.CaptureCallback, Handler)更新任何重复请求 ,然后在序列完成CaptureCallback#onCaptureSequenceCompleted时等待最后一帧编号, 然后再调用 updateOutputConfiguration 删除先前活动的 Surface。
添加的表面不得属于任何其他已注册的 OutputConfiguration.\

CameraCaptureSession.CaptureCallback

一个回调对象,用于跟踪CaptureRequest提交到相机设备的进度。

当请求触发捕获开始以及捕获完成时调用此回调。如果在捕获图像时出错,将触发错误方法而不是完成方法。

onCaptureBufferLost

public void onCaptureBufferLost (CameraCaptureSession session, 
                CaptureRequest request, 
                Surface target, 
                long frameNumber)

如果无法将捕获的单个缓冲区发送到其目标表面,则调用此方法。

如果整个捕获失败,onCaptureFailed(CameraCaptureSession, CaptureRequest, CaptureFailure)则将被调用。如果捕获了一些但不是全部缓冲区,但结果元数据将不可用,则 onCaptureFailed 将被调用并CaptureFailure#wasImageCaptured 返回 true,以及onCaptureBufferLost(CameraCaptureSession, CaptureRequest, Surface, long)对失败输出的一个或多个调用。

拍摄完成

public void onCaptureCompleted (CameraCaptureSession session, 
                CaptureRequest request, 
                TotalCaptureResult result)

当图像捕获完全完成并且所有结果元数据可用时调用此方法。

此回调将始终在最后一个之后触发onCaptureProgressed(CameraCaptureSession, CaptureRequest, CaptureResult);换句话说,一旦完成的结果可用,将不再提供部分结果。

对于延迟是一个因素的性能密集型用例,请考虑onCaptureProgressed(CameraCaptureSession, CaptureRequest, CaptureResult)改用。

此方法的默认实现不执行任何操作。

捕获失败

public void onCaptureFailed (CameraCaptureSession session, 
                CaptureRequest request, 
                CaptureFailure failure)

onCaptureCompleted(CameraCaptureSession, CaptureRequest, TotalCaptureResult)当相机设备未能CaptureResult为请求生成 a 时,将调用此方法。

其他请求不受影响,并且来自捕获的部分或全部图像缓冲区可能已被推送到它们各自的输出流。

此方法的默认实现不执行任何操作。

onCaptureProgressed

public void onCaptureProgressed (CameraCaptureSession session, 
               CaptureRequest request, 
               CaptureResult partialResult)

当图像捕获部分前进时调用此方法;一些(但不是全部)图像捕获结果可用。

此处提供的结果将包含完整结果的某些字段子集。onCaptureProgressed(CameraCaptureSession, CaptureRequest, CaptureResult)每次捕获可能会发生多次调用;给定的结果字段最多只会出现在一个部分捕获中。最终onCaptureCompleted(CameraCaptureSession, CaptureRequest, TotalCaptureResult)调用将始终包含所有字段(特别是组成总结果的所有部分结果的所有字段的并集)。

对于每个请求,某些结果数据可能比其他数据更早可用。每个部分结果(每个请求)之间的典型延迟是单个帧间隔。对于面向性能的用例,应用程序应该查询他们需要的元数据,以便从部分结果中取得进展,并避免等待完成的结果。

对于特定请求,onCaptureProgressed(CameraCaptureSession, CaptureRequest, CaptureResult)可能发生在 之前或之后 onCaptureStarted(CameraCaptureSession, CaptureRequest, long, long)

每个请求至少会产生1部分结果,最多 会产生CameraCharacteristics#REQUEST_PARTIAL_RESULT_COUNT部分结果。

根据请求设置,每个请求的部分结果数会有所不同,但通常部分计数可能相同,只要启用的相机设备子系统保持不变。

此方法的默认实现不执行任何操作。

onCaptureSequenceAborted

public void onCaptureSequenceAborted (CameraCaptureSession session, 
                int sequenceId)

捕获序列在通过此侦听器返回任何CaptureResult 或CaptureFailure为它之前中止时,此方法独立于 CaptureCallback 中的其他方法被调用。

由于相机设备的异步特性,并非所有提交的捕获都会立即处理。可以通过各种操作(例如CameraCaptureSession#stopRepeating或 ) 清除挂起的请求CameraCaptureSession#abortCaptures。当这样的事件发生时, onCaptureSequenceCompleted(CameraCaptureSession, int, long)不会被调用。

默认实现什么都不做。

onCaptureSequenceCompleted

public void onCaptureSequenceCompleted (CameraCaptureSession session, 
                int sequenceId, 
                long frameNumber)

当捕获序列完成并且所有CaptureResult 或CaptureFailure为它已通过此侦听器返回时,此方法独立于 CaptureCallback 中的其他方法调用。

总的来说,在调用此回调之前,此侦听器将返回至少一个结果/失败。如果在处理任何请求之前中止捕获序列,onCaptureSequenceAborted(CameraCaptureSession, int)则改为调用。

默认实现什么都不做。

开始拍摄

public void onCaptureStarted (CameraCaptureSession session, 
                CaptureRequest request, 
                long timestamp, 
                long frameNumber)

当相机设备开始捕获请求的输出图像时,在图像曝光开始时,或者当相机设备已开始处理重新处理请求的输入图像时,将调用此方法。

对于常规捕获请求,此回调在帧捕获开始时调用,因此这是播放快门声音或触发捕获的 UI 指示符的最合适时间。

提供用于此捕获的请求以及开始曝光的实际时间戳。用于再处理请求,该时间戳将曝光的输入图像的开始相匹配the result timestamp field 的TotalCaptureResult那个是用来 create the reprocess request。此时间戳与将包含在the result timestamp field中以及发送到每个输出 Surface 的缓冲区中的时间戳相匹配。这些缓冲区时间戳可通过例如 Image.getTimestamp()或 访问 SurfaceTexture.getTimestamp()。包含的帧编号等于将包含在 中的帧编号 CaptureResult#getFrameNumber

有关播放快门声相机快门或视频录制开始/停止声音的最简单方法,请参阅 MediaActionSound课程。

此方法的默认实现不执行任何操作。

CameraCaptureSession.StateCallback

用于接收有关相机捕获会话状态的更新的回调对象。

活动

public void onActive (CameraCaptureSession session)

当会话开始主动处理捕获请求时调用此方法。

如果onConfigured(CameraCaptureSession)在调用之前提交捕获请求,则会话将在回调后立即开始处理这些请求,并且此方法将在 之后立即调用onConfigured(CameraCaptureSession)

如果会话用完要处理的捕获请求并调用onReady(CameraCaptureSession),则一旦提交新请求进行捕获,将再次调用此回调。

onCaptureQueueEmpty

public void onCaptureQueueEmpty (CameraCaptureSession session)

当相机设备的输入捕获队列变空并准备接受下一个请求时调用此方法。

待处理的捕获请求存在于两个队列之一中:请求已经处于处理管道的不同阶段的进行中队列,以及请求等待进入进行中队列的输入队列。需要输入队列是因为可能提交的请求比当前相机设备管道深度多。

当输入队列变空时会触发此回调,如果设置,相机设备可能不得不回退到重复请求,或者完全跳过传感器的下一帧。例如,这可能会导致相机预览输出出现故障。此回调只会在由 capture() 或 captureBurst() 排队的请求之后触发,而不是在重复请求或突发进入飞行队列之后触发。例如,在重复请求和单次 JPEG 捕获的常见情况下,此回调仅在 JPEG 请求进入进行中的捕获队列时触发。

通过仅发送新的CameraCaptureSession.capture(CaptureRequest, CameraCaptureSession.CaptureCallback, Handler)或当输入队列为空时,可以最大限度地减少管道延迟。CameraCaptureSession.captureBurst(List, CameraCaptureSession.CaptureCallback, Handler)

首次创建会话时不会触发此回调。它不同于 onReady(CameraCaptureSession),当两个队列中的所有请求都被处理完时触发。

关闭

public void onClosed (CameraCaptureSession session)

当会话关闭时调用此方法。

当父相机设备创建新会话或父相机设备关闭(用户关闭设备,或由于相机设备断开连接或致命错误)时,会话将关闭。

一旦会话关闭,其上的所有方法都会抛出 IllegalStateException,并且任何重复的请求或突发都将停止(就像CameraCaptureSession.stopRepeating()被调用一样)。但是,提交到会话的任何正在进行的捕获请求都将正常完成。

配置失败

public abstract void onConfigureFailed (CameraCaptureSession session)

如果无法按请求配置会话,则调用此方法。

如果请求的输出集包含不受支持的大小,或者一次请求过多的输出,就会发生这种情况。

会话被认为是关闭的,并且在调用此回调后对其调用的所有方法都将抛出 IllegalStateException。在此回调之前提交到会话的任何捕获请求都将被丢弃,并且不会在其侦听器上产生任何回调。

已配置

public abstract void onConfigured (CameraCaptureSession session)

当相机设备完成自身配置时调用此方法,会话可以开始处理捕获请求。

如果已经有捕获请求与会话一起排队,一旦调用此回调,它们将开始处理,并且会话将在调用onActive(CameraCaptureSession) 此回调后立即调用。

如果没有提交捕获请求,则会话将 onReady(CameraCaptureSession)在此回调之后立即调用。

如果相机设备配置失败,onConfigureFailed(CameraCaptureSession)则将调用而不是此回调。

准备就绪

public void onReady (CameraCaptureSession session)

每次会话没有更多的捕获请求要处理时,都会调用此方法。

在创建新会话期间,onConfigured(CameraCaptureSession)如果在完成配置之前没有向会话提交捕获请求,则会立即调用此回调 。

否则,只要会话完成处理其所有活动捕获请求,并且没有设置重复请求或突发,就会调用此回调。

表面准备

public void onSurfacePrepared (CameraCaptureSession session, 
                Surface surface)

当输出 Surface 的缓冲区预分配完成时调用此方法。

输出 Surface 的缓冲区预分配由CameraCaptureSession.prepare(Surface)调用开始。在分配过程中,不得将 Surface 用作捕获目标。一旦触发此回调,提供的输出 Surface 可以再次用作捕获请求的目标。

如果在预分配期间发生错误(例如用完合适的内存),则在遇到错误后仍会调用此回调,尽管某些缓冲区可能尚未成功预分配。

CameraConstrainedHighSpeedCaptureSession

CameraDevice的受限高速捕获会话,用于从CameraDevice捕获高速图像以进行高速视频录制用例。
CameraConstrainedHighSpeedCaptureSession是通过向CameraDevice#createCaptureSession(SessionConfiguration)提供一种SessionConfiguration.session(高速)类型的会话配置来创建的。然后,可以将从CameraCaptureSession.StateCallback返回的CameraCaptureSession转换为CameraConstrainedHighSpeedCaptureSession。一旦创建,会话将处于活动状态,直到相机设备创建新会话或相机设备关闭。
活动高速捕获会话是一种专门的捕获会话,仅针对高速视频录制(>=120fps)用例,前提是摄像头设备支持高速视频功能(即CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES contains CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO)。它只接受通过createHighSpeedRequestList(CaptureRequest)创建的请求列表,并且请求列表只能通过captureBurst或setRepeatingBurst提交到此会话。有关限制的更多详细信息,请参阅CameraDevice#createCaptureSession(android.hardware.camera2.params.SessionConfiguration)
创建会话是一项耗时操作,可能需要数百毫秒,因为它需要配置相机设备的内部管道并分配内存缓冲区以将图像发送到所需的目标。因此设置是异步完成的,发送并 CameraDevice#createConstrainedHighSpeedCaptureSession将发送可用的 CameraCaptureSession 到提供 CameraCaptureSession.StateCallback#onConfigured回调。如果无法完成配置,则调用CameraCaptureSession.StateCallback#onConfigureFailed ,并且会话不会变为活动状态。
如果摄像头设备创建了一个新会话,则关闭前一个会话,并onClosed调用其关联的回调。如果在会话关闭后调用,所有会话方法都将抛出 IllegalStateException
CameraCaptureSession.stopRepeating()在新创建的会话接管并重新配置相机设备之前, 关闭的会话会清除任何重复的请求(就像已被调用一样),但仍将正常完成所有正在进行的捕获请求

创建高速请求列表

public abstract List<CaptureRequest> createHighSpeedRequestList (CaptureRequest request)

创建适用于受限高速捕获会话流的不可修改的请求列表。
高速视频流给相机设备带来了巨大的性能压力,因此要实现高效的高速流传输,相机设备可能必须将多个帧聚合在一起。这意味着请求必须分批发送,所有请求共享相同的设置。此方法采用输出目标 Surface 列表(取决于受约束的高速会话指定的输出 Surface 要求)和request,并生成对每个请求具有相同控件的请求列表。输入request必须包含目标输出表面和目标高速 FPS 范围,这是 StreamConfigurationMap#getHighSpeedVideoFpsRangesFor表面大小之一。
如果在'request'中同时指定了预览和录制表面,则输入'request'中的'target FPS range'必须是固定帧速率FPS range,其中'minimal FPS=='maximum FPS。创建的请求列表将包含交错请求模式,以便预览输出FPS至少为30fps,记录输出FPS为请求的FPS范围的“最大FPS”。应用程序可以将此请求列表直接提交到活动的高速捕获会话,以实现高速视频录制。当仅指定预览或录制曲面时,此方法将返回一个请求列表,其中所有请求都具有相同的控件和输出目标。
提交此方法创建一个请求列表,以正常拍摄会话将导致IllegalArgumentException如果高速 FPS range不被支持 CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES