找回密码
 注册
搜索
查看: 2222|回复: 4

[资料] Android Camera数据流完整分析(二)

[复制链接]
发表于 2013-7-8 18:08:09 | 显示全部楼层 |阅读模式
这里还是花一点时间说说camera的打开过程,从app调用到的open方法过程这之前的文章中已经讲过,在底层的open方法中完成以下工作

1.为上层调用注册调用接口

2.实例化hal层,并初始化,这个hal层初始化的过程同样之前的文章中已经详细讲过,这个初始化过程非常重要,直接影响着之后的操作

回到我们的startPreview,一步一步看看他的走向

app层---------------------------做一些基本初始化,最重要的就是setPreviewwindow这个方法了,之前也已经详细分析过了,然后调用frameworks层的方法

frameworks层 ---------------这里只是定义了startPreview这个方式,通过JNI层调用

JNI层---------------------------这里作为一个中间站,不做任何处理,转去调用下一层实现

camera client层-------------同样可以理解为一个中转站,通过binder机制接着往下走

camera server层------------初始化显示窗口属性,调用下一层

hardware interface层------转调camerahal_module中的方法

camera hal层----------------这个hal层的startPreview实现是整个preview过程中最为重要的部分,下面再说明

下面就是通过hal层分发命令通过V4LCameraAdapter或者OMXCameraAdapter与kernel driver进行交互

我们看一下server层的调用,相对较重要


[html]
status_t CameraService::Client::startPreview() {
    LOG1("startPreview (pid %d)", getCallingPid());
    return startCameraMode(<SPAN style="BACKGROUND-COLOR: rgb(51,255,51)">CAMERA_PREVIEW_MODE</SPAN>);
}

status_t CameraService::Client::startPreview() {
    LOG1("startPreview (pid %d)", getCallingPid());
    return startCameraMode(CAMERA_PREVIEW_MODE);
}[html] view plaincopyprint?// start preview or recording
status_t CameraService::Client::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.
            }
            <SPAN style="BACKGROUND-COLOR: rgb(51,255,51)">return startPreviewMode();</SPAN>
        case CAMERA_RECORDING_MODE:
            if (mSurface == 0 && mPreviewWindow == 0) {
                LOGE("mSurface or mPreviewWindow must be set before startRecordingMode.");
                return INVALID_OPERATION;
            }
            return startRecordingMode();
        default:
            return UNKNOWN_ERROR;
    }
}

// start preview or recording
status_t CameraService::Client::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) {
                LOGE("mSurface or mPreviewWindow must be set before startRecordingMode.");
                return INVALID_OPERATION;
            }
            return startRecordingMode();
        default:
            return UNKNOWN_ERROR;
    }
}[html] view plaincopyprint?status_t CameraService::Client::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) {
        native_window_set_scaling_mode(mPreviewWindow.get(),
                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
        native_window_set_buffers_transform(mPreviewWindow.get(),
                mOrientation);
    }

#ifdef OMAP_ENHANCEMENT
    disableMsgType(CAMERA_MSG_COMPRESSED_BURST_IMAGE);
#endif

    mHardware->setPreviewWindow(mPreviewWindow);
    result = mHardware->startPreview();

    return result;
}

status_t CameraService::Client::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) {
        native_window_set_scaling_mode(mPreviewWindow.get(),
                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
        native_window_set_buffers_transform(mPreviewWindow.get(),
                mOrientation);
    }

#ifdef OMAP_ENHANCEMENT
    disableMsgType(CAMERA_MSG_COMPRESSED_BURST_IMAGE);
#endif

    mHardware->setPreviewWindow(mPreviewWindow);
    result = mHardware->startPreview();

    return result;
}
在这个startPreviewMode方法中,同样对previewWindow进行了着重的初始化,这个window一直都是非常重要的,这里我一直没有说到setPreviewwindow这个方法的调用,只是因为这片文章的重点不在这里,但是不代表你可以小视他
发表于 2013-7-9 09:42:36 | 显示全部楼层
肤浅!!!
点评回复

使用道具 举报

发表于 2013-8-21 15:42:03 | 显示全部楼层
讲的太概括了!  
希望版主讲的更详细! 我很想知道hal层的一些具体调用!
点评回复

使用道具 举报

发表于 2013-9-6 13:43:43 | 显示全部楼层
难点在hal层,尤其是没资料
点评回复

使用道具 举报

发表于 2013-9-11 16:51:47 | 显示全部楼层
希望版主讲的更详细!
点评回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

Archiver|手机版|小黑屋|52RD我爱研发网 ( 沪ICP备2022007804号-2 )

GMT+8, 2024-11-23 03:06 , Processed in 0.043694 second(s), 17 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表