高通sdm660android9.0平台camera HAL1中获取并修改预览数据

前言:

最近在做一个有关于HDMI IN的需求,需要找到传入数据的buffer地址,方便以后如果有修改数据的需求的话,可以快速实现,参考了很多人的博客,在此记录一下寻找的过程,一点愚见,希望大家多多指教。

手上平台使用的是HAL1。

参考:

android Camera API1+HAL1 open camera流程 & Android M_徐而思齐的博客-CSDN博客

android camera mmap,Android Camera 流程学习记录(四)—— Camera.startPreview() flow_Robby Robby的博客-CSDN博客

【Camera专题】HAL层-深入浅出startPreview - 简书

Camera HAL(Camera Preview)_honghong96的博客-CSDN博客_camera preview

Android4.4 Camera callback注册和回调过程分析_哇小明的博客-CSDN博客_callback接口

高通camera框架之如何打通App-Hardware经络_简一商业的博客-CSDN博客

分析:

硬件上是通过一个ic芯片将HDMI IN数据流转换成MIPI CSI,再一步步传输给上层;所以对于camera HAL来说,它在获取HDMI IN的数据和摄像头的数据所经历的过程是一样的。

由于HDMI IN的功能是通过打开应用camera预览来进行显示的,这里从camera的预览作为切入点:

追踪 Camera.startPreview() 方法:

以下为摘抄内容:

1. Frameworks

1.1 Camera.java位置:frameworks/base/core/java/android/hardware/Camera.java

startPreview():

给上层 application 提供一个接口。

进入 Runtime 层。

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 = get_native_camera(env, thiz, NULL);
    if (camera == 0) return;
    if (camera->startPreview() != NO_ERROR) {
        jniThrowRuntimeException(env, "startPreview failed");
        return;
    }
}

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 函数进入具体的实现逻辑。

// 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;
    }
}

根据传入的参数 CAMERA_PREVIEW_MODE 肯定进入的分支。

调用 startPreviewMode() 。

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) {
        sCameraService->updateProxyDeviceState(
            hardware::ICameraServiceProxy::CAMERA_STATE_ACTIVE,
            mCameraIdStr, mCameraFacing, mClientPackageName,
            hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
    }
    return result;
}

若是预览已经存在,则直接返回成功信息。

若是未存在,则继续往下走。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值