android 為網路攝影機增加閃光燈(s5pv210)

來源:互聯網
上載者:User

昨天剛好閃光燈弄過來,今天簡單的做下總結。大概的說下,具體我也沒有深入研究,不過效果確實是有了。

首先找到android拍照的時候所執行的函數代碼在:

packages/apps/Camera/src/com/android/camera/Camera.java

找到這個地方:

            mCameraDevice.setParameters(mParameters);            mCameraDevice.takePicture(mShutterCallback, mRawPictureCallback,                    mPostViewPictureCallback, new JpegPictureCallback(loc));            mPreviewing = false;

據我理解,這裡就是拍照的時候所執行的,而這裡應該是調用的camera庫裡的takepicture下面我們找到庫檔案:

device/samsung/proprietary/libcamera

庫檔案就在這裡,下面我們進入SeccameraHWInterface.cpp檔案尋找takepicture如下:

status_t CameraHardwareSec::takePicture(){    LOGV("%s :", __func__);    stopPreview();    Mutex::Autolock lock(mStateLock);    if (mCaptureInProgress) {        LOGE("%s : capture already in progress", __func__);        return INVALID_OPERATION;    }    if (mPictureThread->run("CameraPictureThread", PRIORITY_DEFAULT) != NO_ERROR) {        LOGE("%s : couldn't run picture thread", __func__);        return INVALID_OPERATION;    }    mCaptureInProgress = true;    return NO_ERROR;}

裡面的mPictureThread->run就是拍照的東西了,具體我就不分析了。接下來我們找下閃光燈的介面

在SecCamera.h裡你會發現下面三個函數介面:

    bool            getFlashSupport(void);    int             setFlashMode(int flash_mode);    int             getFlashMode(void);

其中setFlashMode即為設定閃光燈的介面,找到這個函數

在SecCamera.cpp裡如下:

int SecCamera::setFlashMode(int flash_mode){    LOGV("%s(flash_mode(%d))", __func__, flash_mode);    if (flash_mode <= FLASH_MODE_BASE || FLASH_MODE_MAX <= flash_mode) {        LOGE("ERR(%s):Invalid flash_mode (%d)", __func__, flash_mode);        return -1;    }    if (m_params->flash_mode != flash_mode) {        m_params->flash_mode = flash_mode;        if (m_flag_camera_start) {            if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FLASH_MODE, flash_mode) < 0) {                LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FLASH_MODE", __func__);                return -1;            }        }    }    return 0;}

這裡又會調用fimc_v4l2_s_ctrl函數代碼如下:

static int fimc_v4l2_s_ctrl(int fp, unsigned int id, unsigned int value){    struct v4l2_control ctrl;    int ret;    ctrl.id = id;    ctrl.value = value;    //LOGD("%s :--------------------------value is %d",__func__,value);//add dao    ret = ioctl(fp, VIDIOC_S_CTRL, &ctrl);    if (ret < 0) {        LOGE("ERR(%s):VIDIOC_S_CTRL(id = %#x (%d), value = %d) failed ret = %d\n",             __func__, id, id-V4L2_CID_PRIVATE_BASE, value, ret);        return ret;    }    return ctrl.value;}

在這裡進行了ioctl下面我們到核心裡面去看看。
在核心下面的drivers/media/video/v4l2-ioctl.c有如下代碼:

case VIDIOC_S_CTRL:{struct v4l2_control *p = arg;struct v4l2_ext_controls ctrls;struct v4l2_ext_control ctrl;if (!ops->vidioc_s_ctrl && !ops->vidioc_s_ext_ctrls)break;dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);if (ops->vidioc_s_ctrl) {ret = ops->vidioc_s_ctrl(file, fh, p);break;}if (!ops->vidioc_s_ext_ctrls)break;ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);ctrls.count = 1;ctrls.controls = &ctrl;ctrl.id = p->id;ctrl.value = p->value;if (check_ext_ctrls(&ctrls, 1))ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls);break;}

很快我就想到了網路攝影機驅動裡有這樣的設定:

代碼在drivers/media/video/samsung/ficm/ov2640.c

static const struct v4l2_subdev_core_ops ov2640_core_ops = {.init = ov2640_init,/* initializing API */.s_config = ov2640_s_config,/* Fetch platform data */.queryctrl = ov2640_queryctrl,.querymenu = ov2640_querymenu,.g_ctrl = ov2640_g_ctrl,.s_ctrl = ov2640_s_ctrl,};

這裡有一個s_ctrl,事實證明確實是執行了ov2640_s_ctrl至於怎麼調用過來的沒有深入研究。

下面我們看到這個函數開始的部分

static int ov2640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl){struct i2c_client *client = v4l2_get_subdevdata(sd);struct ov2640_state *state = to_state(sd);int err = 0;int value = ctrl->value;switch (ctrl->id) {case V4L2_CID_CAMERA_FLASH_MODE:case V4L2_CID_CAMERA_BRIGHTNESS:break;

第一個就是閃光燈的選項,檔案系統裡面設定閃光燈的就是傳入的這個,可沒作任何處理就直接跳出了。下面我在增加閃光燈驅動:

static int flash_ctrl(int mode){int err;err = gpio_request(S5PV210_GPD0(2), "GPD0"); //powerif (err) {printk(KERN_ERR "failed to request GPD0 for ""flashlight power control\n");return err;}gpio_direction_output(S5PV210_GPD0(2), 1);err = gpio_request(S5PV210_GPD0(3), "GPD0"); //modeif (err) {printk(KERN_ERR "failed to request GPD0 for ""flashlight mode control\n");return err;}/*high is flash mode,low is torch mode*/switch(mode) {case FLASH_MODE_ON:gpio_direction_output(S5PV210_GPD0(3), 1);break;case FLASH_MODE_TORCH:gpio_direction_output(S5PV210_GPD0(3), 0);break;default:break;}mdelay(100);gpio_direction_output(S5PV210_GPD0(2), 0);gpio_free(S5PV210_GPD0(2));gpio_free(S5PV210_GPD0(3));return err;}

電路我就不發出來了,流程搞清楚了,大家就好弄了。

修改ov2640_s_ctrl為:

case V4L2_CID_CAMERA_FLASH_MODE:err = flash_ctrl(value);break;

只修改相關設定,其它的不變。現在介面已經全部寫好,在看到檔案系統裡。
在拍照之前加上閃光燈設定,這個可以在庫裡設定也可以在app裡設定,我直接在庫裡設定的,路徑我就不在打了,前面的相關函數已經全部給出了,如下:

status_t CameraHardwareSec::takePicture(){    LOGV("%s :", __func__);    stopPreview();    Mutex::Autolock lock(mStateLock);    if (mCaptureInProgress) {        LOGE("%s : capture already in progress", __func__);        return INVALID_OPERATION;    }    mSecCamera->setFlashMode(FLASH_MODE_ON);//add by dao    if (mPictureThread->run("CameraPictureThread", PRIORITY_DEFAULT) != NO_ERROR) {        LOGE("%s : couldn't run picture thread", __func__);        return INVALID_OPERATION;    }    mCaptureInProgress = true;    return NO_ERROR;}

在拍照之前設定FlashMode為FLASH_MODE_ON模式,結果發現這樣不行,搞了半天終於發現問題所在,直接把setFlashMode改為如下:

int SecCamera::setFlashMode(int flash_mode){    LOGV("%s(flash_mode(%d))", __func__, flash_mode);    fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FLASH_MODE, flash_mode);/*    if (flash_mode <= FLASH_MODE_BASE || FLASH_MODE_MAX <= flash_mode) {        LOGE("ERR(%s):Invalid flash_mode (%d)", __func__, flash_mode);        return -1;    }    if (m_params->flash_mode != flash_mode) {        m_params->flash_mode = flash_mode;        if (m_flag_camera_start) {            if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FLASH_MODE, flash_mode) < 0) {                LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FLASH_MODE", __func__);                return -1;            }        }    }*/    return 0;}

重新編譯庫和核心,下載,結果測試成功。






相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.