camera应用调用之---创建会话(2)

上节说了Open camera成功之后,会返回CameraDeviceImpl,接下来就是创建会话。会话主要创建CameraCaptureSessionImpl

frameworks\base\core\java\android\hardware\camera2\impl\CameraDeviceImpl.java

    public void createCaptureSession(List<Surface> outputs,
            CameraCaptureSession.StateCallback callback, Handler handler)
            throws CameraAccessException {
        List<OutputConfiguration> outConfigurations = new ArrayList<>(outputs.size());
        for (Surface surface : outputs) {
            outConfigurations.add(new OutputConfiguration(surface));
        }
        createCaptureSessionInternal(null, outConfigurations, callback,
                checkAndWrapHandler(handler), /*operatingMode*/ICameraDeviceUser.NORMAL_MODE,
                /*sessionParams*/ null);
}

先是将Surface转换为OutputConfiguration
先看下Surface调用的地方

packages\apps\Camera2\src\com\android\camera\one\v2\OneCameraImpl.java
outputSurfaces.add(previewSurface);
outputSurfaces.add(mCaptureImageReader.getSurface());
mDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
这个就是多个outputSurfaces集合
看下定义的地方
public final class OutputConfiguration implements Parcelable {
是一个进程间共享的数据包,管理输出配置(包含增减sufrace 方向 宽高,可以看writeToParcel传递的数据)

private void createCaptureSessionInternal(InputConfiguration inputConfig,
            List<OutputConfiguration> outputConfigurations,
            CameraCaptureSession.StateCallback callback, Executor executor,
            int operatingMode, CaptureRequest sessionParams) throws CameraAccessException {
……
	// 如果调用createConstrainedHighSpeedCaptureSession 这个参数就为ture,在open的时候查看//metadata如果支持高帧率,就可以调用它去实现高帧率预览
            boolean isConstrainedHighSpeed =
                    (operatingMode == ICameraDeviceUser.CONSTRAINED_HIGH_SPEED_MODE);
……//1.1 对outputConfigurations检查,是否有配置这些,有删除,没有添加
                configureSuccess = configureStreamsChecked(inputConfig, outputConfigurations,
                        operatingMode, sessionParams);
                if (configureSuccess == true && inputConfig != null) {
                    input = mRemoteDevice.getInputSurface();
                }
……//1.2
                newSession = new CameraCaptureSessionImpl(mNextSessionId++, input,
                        callback, executor, this, mDeviceExecutor, configureSuccess);
……//1.3
mCurrentSession = newSession;

1.1

public boolean configureStreamsChecked(InputConfiguration inputConfig,
List outputs, int operatingMode, CaptureRequest sessionParams)
throws CameraAccessException {

mRemoteDevice.beginConfigure();//执行到CameraDeviceClient::beginConfigure(函数等待实现)
…//1.1.1
// Add all new streams
for (OutputConfiguration outConfig : outputs) {
if (addSet.contains(outConfig)) {
//创建并配置输出流,会执行到CameraDeviceClient::createStream
int streamId = mRemoteDevice.createStream(outConfig);
mConfiguredOutputs.put(streamId, outConfig);
}
}
……//1.1.2
mRemoteDevice.endConfigure(operatingMode, null);

1.1.1

binder::Status CameraDeviceClient::createStream(
        const hardware::camera2::params::OutputConfiguration &outputConfiguration,
        /*out*/
        int32_t* newStreamId) {
……
//该函数如下将OutputConfiguration中的配置信息转换保存到streamInfo (device3下面的对象),里面调用如下:
//surface = new Surface(gbp, useAsync);
// ANativeWindow *anw = surface.get(); 这个就能想起hal1的window
res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer);
……
//添加到 本地surfaces 
 surfaces.push_back(surface);
……//1.1.1.1
    err = mDevice->createStream(surfaces, deferredConsumer, streamInfo.width,
            streamInfo.height, streamInfo.format, streamInfo.dataSpace,
            static_cast<camera3_stream_rotation_t>(outputConfiguration.getRotation()),
            &streamId, physicalCameraId, &surfaceIds, outputConfiguration.getSurfaceSetID(),
            isShared);
……
mStreamMap.add(binder, StreamSurfaceId(streamId, surfaceIds[i]));
……//保存信息,注意上层调用是OutputConfiguration,和这里的名字不一样,这里保存本地
        mConfiguredOutputs.add(streamId, outputConfiguration);
        mStreamInfoMap[streamId] = streamInfo;
status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
        bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
        android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
        const String8& physicalCameraId,
        std::vector<int> *surfaceIds, int streamSetId, bool isShared, uint64_t consumerUsage) {
	......
    } else {
    	// 创建 Camera3OutputStream 实例,consumers是 Surface,
    	 //Camera3OutputStream 的 mConsumer 成员 ,往下调用是Camera3IOStreamBase,再下一级是、、//Camera3Stream,所以最终创建的是Camera3Stream结构,Camera3OutputStream为外包装
        newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
                width, height, format, dataSpace, rotation,
                mTimestampOffset, physicalCameraId, streamSetId);
    }
……
//保存对象
res = mOutputStreams.add(mNextStreamId, newStream);

1.1.2

binder::Status CameraDeviceClient::endConfigure(int operatingMode,
const hardware::camera2::impl::CameraMetadataNative& sessionParams) {

status_t err = mDevice->configureStreams(sessionParams, operatingMode);

}
Camera3Device::configureStreams
–>Camera3Device::filterParamsAndConfigureLocked
–>Camera3Device::configureStreamsLocked
–> mInterface->configureStreams(sessionBuffer, &config, bufferSizes)
–>Camera3Device::HalInterface::configureStreams
–>mHidlSession->configureStreams
mHidlSession在Camera3Device.h定义为
sphardware::camera::device::V3_2::ICameraDeviceSession mHidlSession
hardware\interfaces\camera\device\3.2\CameraDeviceSession.cpp
CameraDeviceSession::configureStreams
–>mDevice->ops->configure_streams 这个mDevice之前有赋值
执行hal的camera3_device_ops_t的configure_streams函数
hardware\rockchip\camera\AAL\Camera3HAL.cpp
hal_dev_configure_streams //hal会专门说这个函数

1.2

CameraCaptureSessionImpl(int id, Surface input,
CameraCaptureSession.StateCallback callback, Executor stateExecutor,
android.hardware.camera2.impl.CameraDeviceImpl deviceImpl,
Executor deviceStateExecutor, boolean configureSuccess) {
……//前面初始化参数,后面调用传入回调的onConfigured,跟open的时候相似,获取CameraCaptureSessionImpl
//内部还包含CameraDeviceImpl(ICameraDeviceUserWrapper)(CameraDeviceClient),然后包含//Camera3InputStream 包含Camera3Stream
if (configureSuccess) {
mStateCallback.onConfigured(this);
if (DEBUG) Log.v(TAG, mIdString + “Created session successfully”);
mConfigureSuccess = true;
}
}
CameraCaptureSession.StateCallback类的public abstract void onConfigured(@NonNull CameraCaptureSession session)回调到应用层,通知我们session创建成功了,那么我们就可以使用回调方法中的CameraCaptureSession参数,调用它的setRepeatingRequest方法来下预览了

小结:apk传下surface,调用createCaptureSession,将surface转换成本地的OutputConfiguration,检查下之前是否配置过,如果包含新的配置,调用mRemoteDevice .createStream也就是CameraDeviceClient ::createStream进入到cameraservice。该函数调用createSurfaceFromGbp转换成本地的surface和streamInfo。调用Camera3Device::createStream,这里面new一个Camera3OutputStream。后面调用mDevice->configureStreams配置之前准备好的stream。
最后创建一个会话类CameraCaptureSessionImpl。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用Camera2 API调用系统相机需要以下步骤: 1.添加权限到 AndroidManifest.xml 文件中: ```xml <uses-permission android:name="android.permission.CAMERA" /> ``` 2.在布局文件中添加一个 SurfaceView 用于预览相机图像: ```xml <SurfaceView android:id="@+id/surfaceView" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 3.在 Activity 中获取 SurfaceView 对象并创建 CameraDevice: ```java private CameraDevice cameraDevice; private CaptureRequest.Builder captureRequestBuilder; private SurfaceView surfaceView; private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice camera) { cameraDevice = camera; createCameraPreview(); } @Override public void onDisconnected(CameraDevice camera) { cameraDevice.close(); } @Override public void onError(CameraDevice camera, int error) { cameraDevice.close(); cameraDevice = null; } }; private void openCamera() { CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); try { String cameraId = manager.getCameraIdList()[0]; CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); Size[] outputSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP) .getOutputSizes(SurfaceHolder.class); Size size = outputSizes[0]; manager.openCamera(cameraId, stateCallback, null); } catch (CameraAccessException e) { e.printStackTrace(); } } ``` 4.为 CameraDevice 创建预览会话: ```java private void createCameraPreview() { try { SurfaceHolder holder = surfaceView.getHolder(); holder.setFixedSize(size.getWidth(), size.getHeight()); holder.setKeepScreenOn(true); final Surface surface = holder.getSurface(); captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); captureRequestBuilder.addTarget(surface); cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession session) { try { CaptureRequest captureRequest = captureRequestBuilder.build(); session.setRepeatingRequest(captureRequest, null, null); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onConfigureFailed(CameraCaptureSession session) { Toast.makeText(MainActivity.this, "Failed to configure camera", Toast.LENGTH_SHORT).show(); } }, null); } catch (CameraAccessException e) { e.printStackTrace(); } } ``` 5.在 Activity 的 onResume() 方法中调用 openCamera() 方法: ```java @Override protected void onResume() { super.onResume(); openCamera(); } ``` 6.在 Activity 的 onPause() 方法中释放相机资源: ```java @Override protected void onPause() { super.onPause(); if (cameraDevice != null) { cameraDevice.close(); cameraDevice = null; } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值