android.hardware.camera2系列----CameraCaptureSession

上篇文章中我们讲了CameraDevice,其中有关于CameraCaptureSession的概念,我们没有详细说明,本篇就来看下CameraCaptureSession是什么。

frameworks\base\core\java\android\hardware\camera2\CameraCaptureSession.java

我们知道在openCamera的时候,CameraApp拿到了CameraDevice的对象,但是在后续请求预览、拍照的操作中,CameraApp却并不是直接拿这个CameraDevice对象去操作,而是通过一个CameraCaptureSession的对象去操作。

CameraCaptureSession到时是什么呢?

A configured capture session for a {@link CameraDevice}, used for capturing images from the camera or reprocessing images captured from the camera in the same session previously.

这是CameraCaptureSession.java文件中的第一行类注释。

Session翻译过来是 会话 的意思,就是说CameraApp要与CameraDevice通信,需要通过这个 会话 来传递。一个CameraDevice对应一个active的CameraCaptureSession。我们可以在一个CameraDevice上去多次创建session,但是在每次创建新session之前,会先判断当前CameraDevice是否已经存在一个CameraCaptureSession对象,有的话,就先close这个session对象,在继续创建新的session对象。

下面我们来看下CameraCaptureSession中的关键方法

  • public abstract CameraDevice getDevice();
    获取当前CameraCaptureSession关联的CameraDevice对象,由此也说明CameraCaptureSession与CameraDevice是一对一的关系

  • public abstract void prepare(@NonNull Surface surface)
    根据方法注释,prepare方法主要是做一些Pre-allocate的动作,保证后续操作的流畅

  • public abstract void tearDown(@NonNull Surface surface)
    释放参数surface对象已经分配的buffer

  • public abstract int capture(@NonNull CaptureRequest request,@Nullable CaptureCallback listener, @Nullable Handler handler)
    拍照方法,参数有 CaptureRequest、listener、handler

  • public abstract int setRepeatingRequest(@NonNull CaptureRequest request, @Nullable CaptureCallback listener, @Nullable Handler handler)
    开启预览

  • public abstract void stopRepeating()
    停止预览

  • public abstract void close();
    关闭当前CameraCaptureSession

与之前的CameraDevice、CameraDeviceImpl实现类似,CameraCaptureSession也是一个抽象类,其具体实现类是CameraCaptureSessionImpl

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

我们随便看几个上面提到的方法

@Override
public CameraDevice getDevice() {
    return mDeviceImpl;
}

@Override
public void prepare(Surface surface) throws CameraAccessException {
    synchronized (mDeviceImpl.mInterfaceLock) {
        checkNotClosed();
        mDeviceImpl.prepare(surface);
    }
}

@Override
public void tearDown(Surface surface) throws CameraAccessException {
    synchronized (mDeviceImpl.mInterfaceLock) {
        checkNotClosed();
        mDeviceImpl.tearDown(surface);
    }
}

@Override
public int capture(CaptureRequest request, CaptureCallback callback,
        Handler handler) throws CameraAccessException {
    checkCaptureRequest(request);

    synchronized (mDeviceImpl.mInterfaceLock) {
        checkNotClosed();

        handler = checkHandler(handler, callback);

        if (DEBUG) {
            Log.v(TAG, mIdString + "capture - request " + request + ", callback " + callback +
                    " handler " + handler);
        }

        return addPendingSequence(mDeviceImpl.capture(request,
                createCaptureCallbackProxy(handler, callback), mDeviceExecutor));
    }
}
.......

我们看到CameraCaptureSessionImpl基本什么都没干,全转给CameraDevice去实现了。

我们可以总结下Camera使用的几个关键节点:
首先,CameraApp去openCamera,得到CameraDevic对象
然后,通过CameraDevice对象去创建 CameraCaptureSession
之后,通过CameraCaptureSession与CameraDevice通信,去起预览、拍照等操作。

本篇内容较短,我们来补充说另一个常见的类:
frameworks\ex\camera2\utils\src\com\android\ex\camera2\utils\ Camera2RequestSettingsSet.java
我们看下代码:

/**
 * A set of settings to be used when filing a {@link CaptureRequest}.
 */
public class Camera2RequestSettingsSet {
    private final Map<Key<?>, Object> mDictionary;
    private long mRevision;

类介绍说这是一个用于填充CaptureRequest的设置类,其成员变量只有两个,其中Map类型的mDictionary就是以键-值对的形式装CameraRequest的参数。

在看它的几个方法:set、remove

public <T> boolean set(Key<T> key, T value) {
    if (key == null) {
        throw new NullPointerException("Received a null key");
    }

    Object currentValue = get(key);
    // Only save the value if it's different from the one we already have
    if (!mDictionary.containsKey(key) || !Objects.equals(value, currentValue)) {
        mDictionary.put(key, value);
        ++mRevision;
        return true;
    }
    return false;
}

public boolean unset(Key<?> key) {
    if (key == null) {
        throw new NullPointerException("Received a null key");
    }

    if (mDictionary.containsKey(key)) {
        mDictionary.remove(key);
        ++mRevision;
        return true;
    }
    return false;
}

最重要的一个方法是提供创建CaptureRequest对象的:

  1. 使用CameraDevice对象,传入要创建的CaptureRequest类型,构建CaptureRequest.Builder对象
  2. 将键值对设置到CaptureRequest.Builder中
public CaptureRequest createRequest(CameraDevice camera, int template, Surface... targets)
            throws CameraAccessException {
        if (camera == null) {
            throw new NullPointerException("Tried to create request using null CameraDevice");
        }

        Builder reqBuilder = camera.createCaptureRequest(template);//使用CameraDevice对象,传入要创建的CaptureRequest.Builder类型
        for (Key<?> key : mDictionary.keySet()) {
            setRequestFieldIfNonNull(reqBuilder, key);//将键值对设置到CaptureRequest.Builder中
        }
        for (Surface target : targets) {
            if (target == null) {
                throw new NullPointerException("Tried to add null Surface as request target");
            }
            reqBuilder.addTarget(target);
        }
        return reqBuilder.build();
    }
private <T> void setRequestFieldIfNonNull(Builder requestBuilder, Key<T> key) {
    T value = get(key);
    if (value != null) {
        requestBuilder.set(key, value);
    }
}

Camera2RequestSettingsSet其实就是对CamraDevice中的createCaptureRequest方法的又一次封装,最大的优点是帮我们管理了需要设置给CaptureRequest的众多参数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值