Android Camera 流程学习记录(四)—— Camera.startPreview() flow

简介
通过整理前几篇笔记,我已经对整个 Camera 的框架有比较清晰的认识,并且也已经渐渐摸清楚了整个控制流的逻辑。
这次,我打算通过追踪 Camera.startPreview() 方法,以加深对控制流的理解。同时尝试结合上一篇关于 module 的认识,将这个流程走到尽可能底部的位置。
Camera.startPreview() flow
1. Frameworks
1.1 Camera.java
位置:frameworks/base/core/java/android/hardware/Camera.java
startPreview(): 
给上层 application 提供一个接口。
进入 Runtime 层。
    /**
     * Starts capturing and drawing preview frames to the screen.
     * Preview will not actually start until a surface is supplied
     * with { @link #setPreviewDisplay(SurfaceHolder)} or
     * { @link #setPreviewTexture(SurfaceTexture)}.
     *
     * <p>If { @link #setPreviewCallback(Camera.PreviewCallback)},
     * { @link #setOneShotPreviewCallback(Camera.PreviewCallback)}, or
     * { @link #setPreviewCallbackWithBuffer(Camera.PreviewCallback)} were
     * called, {@link Camera.PreviewCallback#onPreviewFrame(byte[], Camera)}
     * will be called when preview data becomes available.
     */
    public native final void startPreview();

2. Android Runtime
2.1 android_hardware_Camera.cpp
位置:frameworks/base/core/jni/android_hardware_Camera.cpp
android_hardware_Camera_startPreview(): 
调用 get_native_camera() 函数获取一个 Camera 实例。
调用 Camera::startPreview()。
static void android_hardware_Camera_startPreview(JNIEnv *env, jobject thiz)
{
    ALOGV("startPreview");
    sp<Camera> camera = get_native_camera(env, thiz, NULL);
    if (camera == 0) return;

    if (camera->startPreview() != NO_ERROR) {
        jniThrowRuntimeException(env, "startPreview failed");
        return;
    }
}

get_native_camera(): 
从 DVM 中获取关于 Camera 的上下文。
从上下文信息中获取 Camera 实例。
sp<Camera> get_native_camera(JNIEnv *env, jobject thiz, JNICameraContext** pContext)
{
    sp<Camera> camera;
    Mutex::Autolock _l(sLock);
    JNICameraContext* context = reinterpret_cast<JNICameraContext*>(env->GetLongField(thiz, fields.context));
    if (context != NULL) {
        camera = context->getCamera();
    }
    ALOGV("get_native_camera: context=%p, camera=%p", context, camera.get());
    if (camera == 0) {
        jniThrowRuntimeException(env,
                "Camera is being used after Camera.release() was called");
    }

    if (pContext != NULL) *pContext = context;
    return camera;
}

3. Libraries
3.1 Camera.cpp
位置:frameworks/av/camera/Camera.cpp
startPreview(): 
mCamera 即是在 connect 过程中返回的 CameraClient,它具体实现了 startPreview() 接口。
调用 CameraClient::startPreview()。
// start preview mode
status_t Camera::startPreview()
{
    ALOGV("startPreview");
    sp <::android::hardware::ICamera> c = mCamera;
    if (c == 0) return NO_INIT;
    return c->startPreview();
}

3.2 CameraClient.cpp
位置:frameworks/av/services/camera/libcameraservice/api1/CameraClient.cpp
startPreview(): 
通过 startCameraMode 函数进入具体的实现逻辑。
// start preview mode
status_t CameraClient::startPreview() {
    LOG1("startPreview (pid %d)", getCallingPid());
    return startCameraMode(CAMERA_PREVIEW_MODE);
}

startCameraMode(): 
根据传入的参数 CAMERA_PREVIEW_MODE 确定进入的分支。
调用 startPreviewMode() 。
// start preview or recording
status_t CameraClient::startCameraMode(camera_mode mode) {
    LOG1("startCameraMode(%d)", mode);
    Mutex::Autolock lock(mLock);
    status_t result = checkPidAndHardware();
    if (result != NO_ERROR) return result;

    switch(mode) {
        case CAMERA_PREVIEW_MODE:
            if (mSurface == 0 && mPreviewWindow == 0) {
                LOG1("mSurface is not set yet.");
                // still able to start preview in this case.
            }
            return startPreviewMode();
        case CAMERA_RECORDING_MODE:
            if (mSurface == 0 && mPreviewWindow == 0) {
                ALOGE("mSurface or mPreviewWindow must be set before startRecordingMode.");
                return INVALID_OPERATION;
            }
            return startRecordingMode();
        default:
            return UNKNOWN_ERROR;
    }
}

startPreviewMode(): 
如果预览已经存在,则直接返回成功信息。
如果未存在,则继续往下走。
mHardware 是 CameraHardwareInterface 的实例,在 connect 过程的最后被初始化。
通过 mHardware 调用 setPreviewWindow() 和 startPreview() 接口。
进入 HAL 层。
status_t CameraClient::startPreviewMode() {
    LOG1("startPreviewMode");
    status_t result = NO_ERROR;

    // if preview has been enabled, nothing needs to be done
    if (mHardware->previewEnabled()) {
        return NO_ERROR;
    }

    if (mPreviewWindow != 0) {
        mHardware->setPreviewScalingMode(
            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
        mHardware->setPreviewTransform(mOrientation);
    }
    mHardware->setPreviewWindow(mPreviewWindow);
    result = mHardware->startPreview();
    if (result == NO_ERROR) {
        mCameraService->updateProxyDeviceState(
            ICameraServiceProxy::CAMERA_STATE_ACTIVE,
            String8::format("%d", mCameraId));
    }
    return result;
}

4. HAL
4.1 CameraHardwareInterface.h
位置:frameworks/av/services/camera/libcameraservice/device1/CameraHardwareInterface.h
previewEnable(): 
通过 mDevice->ops 继续向下调用(不是我们主要追踪的)。
mDevice 即是通过 hw_get_module() 相关流程进行初始化的设备实例,它的类型是 camera_device_t 。
如果 preview 存在,则返回 true 。
    /**
     * Returns true if preview is enabled.
     */
    int previewEnabled()
    {
        ALOGV("%s(%s)", __FUNCTION__, mName.string());
        if (mDevice->ops->preview_enabled)
            return mDevice->ops->preview_enabled(mDevice);
        return false;
    }

setPreviewWindow(): 
如果 set_preview_window 函数指针为空,则返回失败信息。
若否,通过 mDevice->ops 继续向下调用(不是我们主要追踪的)。
    /** Set the ANativeWindow to which preview frames are sent */
    status_t setPreviewWindow(const sp<ANativeWindow>& buf)
    {
        ALOGV("%s(%s) buf %p", __FUNCTION__, mName.string(), buf.get());
        if (mDevice->ops->set_preview_window) {
            mPreviewWindow = buf;
            if (buf != nullptr) {
                if (mPreviewScalingMode != NOT_SET) {
                    setPreviewScalingMode(mPreviewScalingMode);
                }
                if (mPreviewTransform != NOT_SET) {
                    setPreviewTransform(mPreviewTransform);
                }
            }
            mHalPreviewWindow.user = this;
            ALOGV("%s &mHalPreviewWindow %p mHalPreviewWindow.user %p", __FUNCTION__,
                    &mHalPreviewWindow, mHalPreviewWindow.user);
            return mDevice->ops->set_preview_window(mDevice,
                    buf.get() ? &mHalPreviewWindow.nw : 0);
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

flybirding10011

谢谢支持啊999

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值