/** * Start auto focus, the notification callback routine is called with * CAMERA_MSG_FOCUS once when focusing is complete. autoFocus() will be * called again if another auto focus is needed. */ static int HAL_camera_device_auto_focus(struct camera_device *dev) { ExynosCameraAutoTimer autoTimer(__func__); ALOGV("DEBUG(%s):", __func__); return obj(dev)->autoFocus(); }
/** * Cancel a picture that was started with takePicture. Calling this method * when no picture is being taken is a no-op. */ static int HAL_camera_device_cancel_picture(struct camera_device *dev) { ExynosCameraAutoTimer autoTimer(__func__); ALOGV("DEBUG(%s):", __func__); return obj(dev)->cancelPicture(); }
/** * Disable a message, or a set of messages. * * Once received a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), camera * HAL should not rely on its client to call releaseRecordingFrame() to * release video recording frames sent out by the cameral HAL before and * after the disableMsgType(CAMERA_MSG_VIDEO_FRAME) call. Camera HAL * clients must not modify/access any video recording frame after calling * disableMsgType(CAMERA_MSG_VIDEO_FRAME). */ static void HAL_camera_device_disable_msg_type(struct camera_device *dev, int32_t msg_type) { ExynosCameraAutoTimer autoTimer(__func__); ALOGV("DEBUG(%s):", __func__); obj(dev)->disableMsgType(msg_type); }
/** * Release the hardware resources owned by this object. Note that this is * *not* done in the destructor. */ static void HAL_camera_device_release(struct camera_device *dev) { ExynosCameraAutoTimer autoTimer(__func__); int cameraId = obj(dev)->getCameraId(); enum CAMERA_STATE state; ALOGI("[INFO] (%s:%d):camera(%d) in", __func__, __LINE__, cameraId); state = CAMERA_RELEASED; if (check_camera_state(state, cameraId) == false) { ALOGE("ERR(%s):camera(%d) state(%d) is INVALID", __func__, cameraId, state); return; } g_cam_openLock[cameraId].lock(); obj(dev)->release(); ALOGI("[INFO] (%s:%d):camera(%d) out from release()", __func__, __LINE__, cameraId); g_cam_openLock[cameraId].unlock(); ALOGI("[INFO] (%s:%d):camera(%d) unlocked..", __func__, __LINE__, cameraId); cam_stateLock[cameraId].lock(); cam_state[cameraId] = state; cam_stateLock[cameraId].unlock(); ALOGI("[INFO] (%s:%d):camera(%d) out", __func__, __LINE__, cameraId); }
static void HAL_camera_device_put_parameters(struct camera_device *dev, char *parms) { ExynosCameraAutoTimer autoTimer(__func__); ALOGV("DEBUG(%s):", __func__); free(parms); }
/** * Start record mode. When a record image is available, a * CAMERA_MSG_VIDEO_FRAME message is sent with the corresponding * frame. Every record frame must be released by a camera HAL client via * releaseRecordingFrame() before the client calls * disableMsgType(CAMERA_MSG_VIDEO_FRAME). After the client calls * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is the camera HAL's * responsibility to manage the life-cycle of the video recording frames, * and the client must not modify/access any video recording frames. */ static int HAL_camera_device_start_recording(struct camera_device *dev) { ExynosCameraAutoTimer autoTimer(__func__); static int ret; int cameraId = obj(dev)->getCameraId(); enum CAMERA_STATE state; ALOGI("[INFO] (%s:%d):camera(%d) in", __func__, __LINE__, cameraId); state = CAMERA_RECORDING; if (check_camera_state(state, cameraId) == false) { ALOGE("ERR(%s):camera(%d) state(%d) is INVALID", __func__, cameraId, state); return -1; } g_cam_recordingLock[cameraId].lock(); ret = obj(dev)->startRecording(); ALOGI("[INFO] (%s:%d):camera(%d) out from startRecording()", __func__, __LINE__, cameraId); g_cam_recordingLock[cameraId].unlock(); ALOGI("[INFO] (%s:%d):camera(%d) unlocked..", __func__, __LINE__, cameraId); if (ret == OK) { cam_stateLock[cameraId].lock(); cam_state[cameraId] = state; cam_stateLock[cameraId].unlock(); ALOGI("[INFO] (%s:%d):camera(%d) out (startRecording succeeded)", __func__, __LINE__, cameraId); } else { ALOGI("[INFO] (%s:%d):camera(%d) out (startRecording FAILED)", __func__, __LINE__, cameraId); } return ret; }
/** * Returns true if recording is enabled. */ static int HAL_camera_device_recording_enabled(struct camera_device *dev) { ExynosCameraAutoTimer autoTimer(__func__); ALOGV("DEBUG(%s):", __func__); return obj(dev)->recordingEnabled(); }
/** * Request the camera HAL to store meta data or real YUV data in the video * buffers sent out via CAMERA_MSG_VIDEO_FRAME for a recording session. If * it is not called, the default camera HAL behavior is to store real YUV * data in the video buffers. * * This method should be called before startRecording() in order to be * effective. * * If meta data is stored in the video buffers, it is up to the receiver of * the video buffers to interpret the contents and to find the actual frame * data with the help of the meta data in the buffer. How this is done is * outside of the scope of this method. * * Some camera HALs may not support storing meta data in the video buffers, * but all camera HALs should support storing real YUV data in the video * buffers. If the camera HAL does not support storing the meta data in the * video buffers when it is requested to do do, INVALID_OPERATION must be * returned. It is very useful for the camera HAL to pass meta data rather * than the actual frame data directly to the video encoder, since the * amount of the uncompressed frame data can be very large if video size is * large. * * @param enable if true to instruct the camera HAL to store * meta data in the video buffers; false to instruct * the camera HAL to store real YUV data in the video * buffers. * * @return OK on success. */ static int HAL_camera_device_store_meta_data_in_buffers(struct camera_device *dev, int enable) { ExynosCameraAutoTimer autoTimer(__func__); ALOGV("DEBUG(%s):", __func__); return obj(dev)->storeMetaDataInBuffers(enable); }
static int HAL_getNumberOfCameras() { ExynosCameraAutoTimer autoTimer(__func__); ALOGV("DEBUG(%s):", __func__); return sizeof(sCameraInfo) / sizeof(sCameraInfo[0]); }
/** * Query whether a message, or a set of messages, is enabled. Note that * this is operates as an AND, if any of the messages queried are off, this * will return false. */ static int HAL_camera_device_msg_type_enabled(struct camera_device *dev, int32_t msg_type) { ExynosCameraAutoTimer autoTimer(__func__); ALOGV("DEBUG(%s):", __func__); return obj(dev)->msgTypeEnabled(msg_type); }
/** * Dump state of the camera hardware */ static int HAL_camera_device_dump(struct camera_device *dev, int fd) { ExynosCameraAutoTimer autoTimer(__func__); ALOGV("DEBUG(%s):", __func__); return obj(dev)->dump(fd); }
static int HAL_camera_device_open(const struct hw_module_t* module, const char *id, struct hw_device_t** device) { ExynosCameraAutoTimer autoTimer(__func__); int cameraId = atoi(id); enum CAMERA_STATE state; ALOGI("[INFO] (%s:%d):camera(%d) in", __func__, __LINE__, cameraId); if (cameraId < 0 || cameraId >= HAL_getNumberOfCameras()) { ALOGE("ERR(%s):Invalid camera ID %s", __func__, id); return -EINVAL; } state = CAMERA_OPENED; if (check_camera_state(state, cameraId) == false) { ALOGE("ERR(%s):camera(%d) state(%d) is INVALID", __func__, cameraId, state); return -1; } if (cameraId < (sizeof(sCameraInfo) / sizeof(sCameraInfo[0]))) { if (g_cam_device[cameraId]) { ALOGE("DEBUG(%s):returning existing camera ID %s", __func__, id); *device = (hw_device_t *)g_cam_device[cameraId]; goto done; } g_cam_device[cameraId] = (camera_device_t *)malloc(sizeof(camera_device_t)); if (!g_cam_device[cameraId]) return -ENOMEM; g_cam_openLock[cameraId].lock(); g_cam_device[cameraId]->common.tag = HARDWARE_DEVICE_TAG; g_cam_device[cameraId]->common.version = 1; g_cam_device[cameraId]->common.module = const_cast<hw_module_t *>(module); g_cam_device[cameraId]->common.close = HAL_camera_device_close; g_cam_device[cameraId]->ops = &camera_device_ops; ALOGE("DEBUG(%s):open camera %s", __func__, id); g_cam_device[cameraId]->priv = new ExynosCameraHWImpl(cameraId, g_cam_device[cameraId]); *device = (hw_device_t *)g_cam_device[cameraId]; ALOGI("[INFO] (%s:%d):camera(%d) out from new g_cam_device[%d]->priv()", __func__, __LINE__, cameraId, cameraId); g_cam_openLock[cameraId].unlock(); ALOGI("[INFO] (%s:%d):camera(%d) unlocked..", __func__, __LINE__, cameraId); } else { ALOGE("DEBUG(%s):camera(%s) open fail - must front camera open first", __func__, id); return -EINVAL; } done: cam_stateLock[cameraId].lock(); cam_state[cameraId] = state; cam_stateLock[cameraId].unlock(); ALOGI("[INFO] (%s:%d):camera(%d) out", __func__, __LINE__, cameraId); return 0; }
/** * Send command to camera driver. */ static int HAL_camera_device_send_command(struct camera_device *dev, int32_t cmd, int32_t arg1, int32_t arg2) { ExynosCameraAutoTimer autoTimer(__func__); ALOGV("DEBUG(%s):", __func__); return obj(dev)->sendCommand(cmd, arg1, arg2); }
/** * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME. * * It is camera HAL client's responsibility to release video recording * frames sent out by the camera HAL before the camera HAL receives a call * to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives the call to * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is the camera HAL's * responsibility to manage the life-cycle of the video recording frames. */ static void HAL_camera_device_release_recording_frame(struct camera_device *dev, const void *opaque) { ExynosCameraAutoTimer autoTimer(__func__); ALOGV("DEBUG(%s):", __func__); obj(dev)->releaseRecordingFrame(opaque); }
/** Return the camera parameters. */ char *HAL_camera_device_get_parameters(struct camera_device *dev) { ExynosCameraAutoTimer autoTimer(__func__); ALOGV("DEBUG(%s):", __func__); String8 str; CameraParameters parms = obj(dev)->getParameters(); str = parms.flatten(); return strdup(str.string()); }
/** * Set the camera parameters. This returns BAD_VALUE if any parameter is * invalid or not supported. */ static int HAL_camera_device_set_parameters(struct camera_device *dev, const char *parms) { ExynosCameraAutoTimer autoTimer(__func__); ALOGV("DEBUG(%s):", __func__); String8 str(parms); CameraParameters p(str); return obj(dev)->setParametersLocked(p); }
/** Set the preview_stream_ops to which preview frames are sent */ static int HAL_camera_device_set_preview_window(struct camera_device *dev, struct preview_stream_ops *buf) { ExynosCameraAutoTimer autoTimer(__func__); static int ret; int cameraId = obj(dev)->getCameraId(); ALOGI("[INFO] (%s:%d):camera(%d) in", __func__, __LINE__, cameraId); ret = obj(dev)->setPreviewWindowLocked(buf); ALOGI("[INFO] (%s:%d):camera(%d) out", __func__, __LINE__, cameraId); return ret; }
/** Set the notification and data callbacks */ static void HAL_camera_device_set_callbacks(struct camera_device *dev, camera_notify_callback notify_cb, camera_data_callback data_cb, camera_data_timestamp_callback data_cb_timestamp, camera_request_memory get_memory, void* user) { ExynosCameraAutoTimer autoTimer(__func__); ALOGV("DEBUG(%s):", __func__); obj(dev)->setCallbacks(notify_cb, data_cb, data_cb_timestamp, get_memory, user); }
static void HAL_camera_device_stop_preview(struct camera_device *dev) { ExynosCameraAutoTimer autoTimer(__func__); int cameraId = obj(dev)->getCameraId(); enum CAMERA_STATE state; ALOGI("[INFO] (%s:%d):camera(%d) in", __func__, __LINE__, cameraId); /* HACK : If camera in recording state, */ /* CameraService have to call the stop_recording before the stop_preview */ #if 1 if (cam_state[cameraId] == CAMERA_RECORDING) { ALOGE("(%s:%d) camera(%d) in RECORDING RUNNING state ---- INVALID ----", __func__, __LINE__, cameraId); ALOGE("(%s:%d) camera(%d) The stop_recording must be called " "before the stop_preview ---- INVALID ----", __func__, __LINE__, cameraId); HAL_camera_device_stop_recording(dev); ALOGE("(%s:%d) cameraId=%d out from stop_recording ---- INVALID ----", __func__, __LINE__, cameraId); for (int i=0; i<30; i++) { ALOGE("(%s:%d) camera(%d) The stop_recording must be called " "before the stop_preview ---- INVALID ----", __func__, __LINE__, cameraId); } ALOGE("(%s:%d) camera(%d) sleep 500ms for ---- INVALID ---- state", __func__, __LINE__, cameraId); usleep(500000); /* to notify, sleep 500ms */ } #endif state = CAMERA_PREVIEWSTOPPED; if (check_camera_state(state, cameraId) == false) { ALOGE("ERR(%s):camera(%d) state(%d) is INVALID", __func__, cameraId, state); return; } g_cam_previewLock[cameraId].lock(); obj(dev)->stopPreviewLocked(); ALOGI("[INFO] (%s:%d):camera(%d) out from stopPreviewLocked()", __func__, __LINE__, cameraId); g_cam_previewLock[cameraId].unlock(); ALOGI("[INFO] (%s:%d):camera(%d) unlocked..", __func__, __LINE__, cameraId); cam_stateLock[cameraId].lock(); cam_state[cameraId] = state; cam_stateLock[cameraId].unlock(); ALOGI("[INFO] (%s:%d):camera(%d) out", __func__, __LINE__, cameraId); }
static int HAL_getCameraInfo(int cameraId, struct camera_info *info) { ExynosCameraAutoTimer autoTimer(__func__); ALOGV("DEBUG(%s):", __func__); if (cameraId < 0 || cameraId >= HAL_getNumberOfCameras()) { ALOGE("ERR(%s):Invalid camera ID %d", __func__, cameraId); return -EINVAL; } memcpy(info, &sCameraInfo[cameraId], sizeof(CameraInfo)); info->device_version = HARDWARE_DEVICE_API_VERSION(1, 0); return NO_ERROR; }
static int HAL_camera_device_close(struct hw_device_t* device) { ExynosCameraAutoTimer autoTimer(__func__); int cameraId; enum CAMERA_STATE state; ALOGI("[INFO] (%s:%d): in", __func__, __LINE__); if (device) { camera_device_t *cam_device = (camera_device_t *)device; cameraId = obj(cam_device)->getCameraId(); ALOGI("[INFO] (%s:%d):camera(%d)", __func__, __LINE__, cameraId); state = CAMERA_CLOSED; if (check_camera_state(state, cameraId) == false) { ALOGE("ERR(%s):camera(%d) state(%d) is INVALID", __func__, cameraId, state); return -1; } g_cam_openLock[cameraId].lock(); ALOGI("[INFO] (%s:%d):camera(%d) locked..", __func__, __LINE__, cameraId); g_cam_device[cameraId] = NULL; g_cam_openLock[cameraId].unlock(); ALOGI("[INFO] (%s:%d):camera(%d) unlocked..", __func__, __LINE__, cameraId); delete static_cast<ExynosCameraHWImpl *>(cam_device->priv); free(cam_device); cam_stateLock[cameraId].lock(); cam_state[cameraId] = state; cam_stateLock[cameraId].unlock(); ALOGI("[INFO] (%s:%d):camera(%d)", __func__, __LINE__, cameraId); } ALOGI("[INFO] (%s:%d): out", __func__, __LINE__); return 0; }
status_t ExynosCameraPipeJpeg::m_run(void) { ExynosCameraAutoTimer autoTimer(__FUNCTION__); status_t ret = 0; ExynosCameraFrame *newFrame = NULL; ExynosCameraBuffer yuvBuf; ExynosCameraBuffer jpegBuf; ExynosRect pictureRect; int jpegQuality = m_parameters->getJpegQuality(); ExynosRect thumbnailRect; int thumbnailQuality = m_parameters->getThumbnailQuality(); exif_attribute_t exifInfo; m_parameters->getFixedExifInfo(&exifInfo); struct camera2_shot_ext shot_ext; memset(&shot_ext, 0x00, sizeof(struct camera2_shot_ext)); pictureRect.colorFormat = m_parameters->getPictureFormat(); m_parameters->getPictureSize(&pictureRect.w, &pictureRect.h); m_parameters->getThumbnailSize(&thumbnailRect.w, &thumbnailRect.h); ALOGI("DEBUG(%s[%d]): -IN-", __FUNCTION__, __LINE__); ALOGD("DEBUG(%s[%d]):picture size(%dx%d), thumbnail size(%dx%d)", __FUNCTION__, __LINE__, pictureRect.w, pictureRect.h, thumbnailRect.w, thumbnailRect.h); ret = m_inputFrameQ->waitAndPopProcessQ(&newFrame); if (ret < 0) { /* TODO: We need to make timeout duration depends on FPS */ if (ret == TIMED_OUT) { ALOGW("WARN(%s):wait timeout", __FUNCTION__); } else { ALOGE("ERR(%s):wait and pop fail, ret(%d)", __FUNCTION__, ret); /* TODO: doing exception handling */ } return ret; } if (newFrame == NULL) { ALOGE("ERR(%s):new frame is NULL", __FUNCTION__); return NO_ERROR; } ret = newFrame->getSrcBuffer(getPipeId(), &yuvBuf); if (ret < 0) { CLOGE("ERR(%s[%d]):frame get src buffer fail, ret(%d)", __FUNCTION__, __LINE__, ret); /* TODO: doing exception handling */ return OK; } ret = newFrame->getDstBuffer(getPipeId(), &jpegBuf); if (ret < 0) { CLOGE("ERR(%s[%d]):frame get dst buffer fail, ret(%d)", __FUNCTION__, __LINE__, ret); /* TODO: doing exception handling */ return OK; } if (m_jpegEnc.create()) { ALOGE("ERR(%s):m_jpegEnc.create() fail", __FUNCTION__); ret = INVALID_OPERATION; goto jpeg_encode_done; } if (m_jpegEnc.setQuality(jpegQuality)) { ALOGE("ERR(%s):m_jpegEnc.setQuality() fail", __FUNCTION__); ret = INVALID_OPERATION; goto jpeg_encode_done; } if (m_jpegEnc.setSize(pictureRect.w, pictureRect.h)) { ALOGE("ERR(%s):m_jpegEnc.setSize() fail", __FUNCTION__); ret = INVALID_OPERATION; goto jpeg_encode_done; } if (m_jpegEnc.setColorFormat(pictureRect.colorFormat)) { ALOGE("ERR(%s):m_jpegEnc.setColorFormat() fail", __FUNCTION__); ret = INVALID_OPERATION; goto jpeg_encode_done; } if (m_jpegEnc.setJpegFormat(V4L2_PIX_FMT_JPEG_422)) { ALOGE("ERR(%s):m_jpegEnc.setJpegFormat() fail", __FUNCTION__); ret = INVALID_OPERATION; goto jpeg_encode_done; } if (thumbnailRect.w != 0 && thumbnailRect.h != 0) { exifInfo.enableThumb = true; if (pictureRect.w < 320 || pictureRect.h < 240) { thumbnailRect.w = 160; thumbnailRect.h = 120; } if (m_jpegEnc.setThumbnailSize(thumbnailRect.w, thumbnailRect.h)) { ALOGE("ERR(%s):m_jpegEnc.setThumbnailSize(%d, %d) fail", __FUNCTION__, thumbnailRect.w, thumbnailRect.h); ret = INVALID_OPERATION; goto jpeg_encode_done; } if (0 < thumbnailQuality && thumbnailQuality <= 100) { if (m_jpegEnc.setThumbnailQuality(thumbnailQuality)) { ret = INVALID_OPERATION; ALOGE("ERR(%s):m_jpegEnc.setThumbnailQuality(%d) fail", __FUNCTION__, thumbnailQuality); } } } else { exifInfo.enableThumb = false; } /* wait for medata update */ if(newFrame->getMetaDataEnable() == false) { CLOGD("DEBUG(%s[%d]): Waiting for update jpeg metadata failed (%d) ", __FUNCTION__, __LINE__, ret); } /* get dynamic meters for make exif info */ newFrame->getDynamicMeta(&shot_ext); newFrame->getUserDynamicMeta(&shot_ext); m_parameters->setExifChangedAttribute(&exifInfo, &pictureRect, &thumbnailRect,&shot_ext.shot.dm, &shot_ext.shot.udm); if (m_jpegEnc.setInBuf((int *)&(yuvBuf.fd), (int *)yuvBuf.size)) { ALOGE("ERR(%s):m_jpegEnc.setInBuf() fail", __FUNCTION__); ret = INVALID_OPERATION; goto jpeg_encode_done; } if (m_jpegEnc.setOutBuf(jpegBuf.fd[0], jpegBuf.size[0] + jpegBuf.size[1] + jpegBuf.size[2])) { ALOGE("ERR(%s):m_jpegEnc.setOutBuf() fail", __FUNCTION__); ret = INVALID_OPERATION; goto jpeg_encode_done; } if (m_jpegEnc.updateConfig()) { ALOGE("ERR(%s):m_jpegEnc.updateConfig() fail", __FUNCTION__); ret = INVALID_OPERATION; goto jpeg_encode_done; } if (m_jpegEnc.encode((int *)&jpegBuf.size, &exifInfo, m_parameters->getDebugAttribute())) { ALOGE("ERR(%s):m_jpegEnc.encode() fail", __FUNCTION__); ret = INVALID_OPERATION; goto jpeg_encode_done; } newFrame->setJpegSize(jpegBuf.size[0]); ret = newFrame->setEntityState(getPipeId(), ENTITY_STATE_FRAME_DONE); if (ret < 0) { CLOGE("ERR(%s[%d]):set entity state fail, ret(%d)", __FUNCTION__, __LINE__, ret); /* TODO: doing exception handling */ return OK; } m_outputFrameQ->pushProcessQ(&newFrame); jpeg_encode_done: if (ret != NO_ERROR) { ALOGD("[jpegBuf.fd[0] %d][jpegBuf.size[0] + jpegBuf.size[1] + jpegBuf.size[2] %d]", jpegBuf.fd[0], jpegBuf.size[0] + jpegBuf.size[1] + jpegBuf.size[2]); ALOGD("[pictureW %d][pictureH %d][pictureFormat %d]", pictureRect.w, pictureRect.h, pictureRect.colorFormat); } if (m_jpegEnc.flagCreate() == true) m_jpegEnc.destroy(); ALOGI("DEBUG(%s[%d]): -OUT-", __FUNCTION__, __LINE__); return ret; }