昨天剛好閃光燈弄過來,今天簡單的做下總結。大概的說下,具體我也沒有深入研究,不過效果確實是有了。
首先找到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;
}