| /* Copyright (c) 2011, The Linux Foundation. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following |
| * disclaimer in the documentation and/or other materials provided |
| * with the distribution. |
| * * Neither the name of The Linux Foundation nor the names of its |
| * contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
| * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
| * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
| * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| */ |
| /*#error uncomment this for compiler test!*/ |
| |
| //#define ALOG_NDEBUG 0 |
| #define ALOG_NIDEBUG 0 |
| #define LOG_TAG "QualcommCamera" |
| #include <utils/Log.h> |
| #include <utils/threads.h> |
| #include <fcntl.h> |
| #include <sys/mman.h> |
| |
| #include "QCameraHAL.h" |
| /* include QCamera Hardware Interface Header*/ |
| #include "QualcommCamera2.h" |
| //#include "QualcommCameraHardware.h" |
| //#include <camera/CameraHardwareInterface.h> |
| |
| extern "C" { |
| #include <sys/time.h> |
| } |
| |
| /* HAL function implementation goes here*/ |
| |
| /** |
| * The functions need to be provided by the camera HAL. |
| * |
| * If getNumberOfCameras() returns N, the valid cameraId for getCameraInfo() |
| * and openCameraHardware() is 0 to N-1. |
| */ |
| |
| static hw_module_methods_t camera_module_methods = { |
| open: camera_device_open, |
| }; |
| |
| static hw_module_t camera_common = { |
| tag: HARDWARE_MODULE_TAG, |
| version_major: 0, |
| version_minor: 01, |
| id: CAMERA_HARDWARE_MODULE_ID, |
| name: "Qcamera", |
| author:"Qcom", |
| methods: &camera_module_methods, |
| dso: NULL, |
| //reserved[0]: 0, |
| }; |
| camera_module_t HAL_MODULE_INFO_SYM = { |
| common: camera_common, |
| get_number_of_cameras: get_number_of_cameras, |
| get_camera_info: get_camera_info, |
| }; |
| |
| camera_device_ops_t camera_ops = { |
| set_preview_window: android::set_preview_window, |
| set_callbacks: android::set_CallBacks, |
| enable_msg_type: android::enable_msg_type, |
| disable_msg_type: android::disable_msg_type, |
| msg_type_enabled: android::msg_type_enabled, |
| |
| start_preview: android::start_preview, |
| stop_preview: android::stop_preview, |
| preview_enabled: android::preview_enabled, |
| store_meta_data_in_buffers: android::store_meta_data_in_buffers, |
| |
| start_recording: android::start_recording, |
| stop_recording: android::stop_recording, |
| recording_enabled: android::recording_enabled, |
| release_recording_frame: android::release_recording_frame, |
| |
| auto_focus: android::auto_focus, |
| cancel_auto_focus: android::cancel_auto_focus, |
| |
| take_picture: android::take_picture, |
| cancel_picture: android::cancel_picture, |
| |
| set_parameters: android::set_parameters, |
| get_parameters: android::get_parameters, |
| put_parameters: android::put_parameters, |
| send_command: android::send_command, |
| |
| release: android::release, |
| dump: android::dump, |
| }; |
| |
| namespace android { |
| |
| typedef struct { |
| camera_device hw_dev; |
| //sp<CameraHardwareInterface> hardware; |
| QCameraHardwareInterface *hardware; |
| int camera_released; |
| int cameraId; |
| //QCameraParameters parameters; |
| } camera_hardware_t; |
| |
| typedef struct { |
| camera_memory_t mem; |
| int32_t msgType; |
| sp<IMemory> dataPtr; |
| void* user; |
| unsigned int index; |
| } q_cam_memory_t; |
| |
| QCameraHardwareInterface *util_get_Hal_obj( struct camera_device * device) |
| { |
| QCameraHardwareInterface *hardware = NULL; |
| if(device && device->priv){ |
| camera_hardware_t *camHal = (camera_hardware_t *)device->priv; |
| hardware = camHal->hardware; |
| } |
| return hardware; |
| } |
| |
| #if 0 |
| QCameraParameters* util_get_HAL_parameter( struct camera_device * device) |
| { |
| QCameraParameters *param = NULL; |
| if(device && device->priv){ |
| camera_hardware_t *camHal = (camera_hardware_t *)device->priv; |
| param = &(camHal->parameters); |
| } |
| return param; |
| } |
| #endif |
| extern "C" int get_number_of_cameras() |
| { |
| /* try to query every time we get the call!*/ |
| |
| ALOGV("Q%s: E", __func__); |
| return android::HAL_getNumberOfCameras( ); |
| } |
| |
| extern "C" int get_camera_info(int camera_id, struct camera_info *info) |
| { |
| int rc = -1; |
| ALOGV("Q%s: E", __func__); |
| if(info) { |
| struct CameraInfo camInfo; |
| memset(&camInfo, -1, sizeof (struct CameraInfo)); |
| android::HAL_getCameraInfo(camera_id, &camInfo); |
| if (camInfo.facing >= 0) { |
| rc = 0; |
| info->facing = camInfo.facing; |
| info->orientation = camInfo.orientation; |
| } |
| } |
| ALOGV("Q%s: X", __func__); |
| return rc; |
| } |
| |
| static pthread_mutex_t camera_session_lock = PTHREAD_MUTEX_INITIALIZER; |
| static unsigned int QCameraSession = 0; |
| |
| /* HAL should return NULL if it fails to open camera hardware. */ |
| extern "C" int camera_device_open( |
| const struct hw_module_t* module, const char* id, |
| struct hw_device_t** hw_device) |
| { |
| int rc = -1; |
| int mode = 0; // TODO: need to add 3d/2d mode, etc |
| camera_device *device = NULL; |
| |
| pthread_mutex_lock(&camera_session_lock); |
| |
| //Return INVALID_OPERATION(-1) to framework if multiple camera instances detected. |
| if(QCameraSession) { |
| ALOGE("%s Mutliple camera open instances are not supported",__func__); |
| pthread_mutex_unlock(&camera_session_lock); |
| return rc; |
| } |
| if(module && id && hw_device) { |
| int cameraId = atoi(id); |
| |
| if (!strcmp(module->name, camera_common.name)) { |
| camera_hardware_t *camHal = |
| (camera_hardware_t *) malloc(sizeof (camera_hardware_t)); |
| if(!camHal) { |
| *hw_device = NULL; |
| ALOGE("%s: end in no mem", __func__); |
| pthread_mutex_unlock(&camera_session_lock); |
| return rc; |
| } |
| /* we have the camera_hardware obj malloced */ |
| memset(camHal, 0, sizeof (camera_hardware_t)); |
| camHal->hardware = new QCameraHardwareInterface(cameraId, mode); //HAL_openCameraHardware(cameraId); |
| if (camHal->hardware && camHal->hardware->isCameraReady()) { |
| camHal->cameraId = cameraId; |
| device = &camHal->hw_dev; |
| device->common.close = close_camera_device; |
| device->ops = &camera_ops; |
| device->priv = (void *)camHal; |
| QCameraSession++; |
| rc = 0; |
| } else { |
| if (camHal->hardware) { |
| delete camHal->hardware; |
| camHal->hardware = NULL; |
| } |
| free(camHal); |
| device = NULL; |
| } |
| } |
| } |
| /* pass actual hw_device ptr to framework. This amkes that we actally be use memberof() macro */ |
| *hw_device = (hw_device_t*)&device->common; |
| ALOGV("%s: end rc %d", __func__, rc); |
| pthread_mutex_unlock(&camera_session_lock); |
| return rc; |
| } |
| |
| extern "C" int close_camera_device( hw_device_t *hw_dev) |
| { |
| ALOGV("Q%s: device =%p E", __func__, hw_dev); |
| int rc = -1; |
| camera_device_t *device = (camera_device_t *)hw_dev; |
| |
| pthread_mutex_lock(&camera_session_lock); |
| |
| if(device) { |
| camera_hardware_t *camHal = (camera_hardware_t *)device->priv; |
| if(camHal ) { |
| QCameraHardwareInterface *hardware = util_get_Hal_obj( device); |
| if(!camHal->camera_released) { |
| if(hardware != NULL) { |
| hardware->release( ); |
| } |
| } |
| if (QCameraSession) |
| QCameraSession--; |
| if(hardware != NULL) |
| delete hardware; |
| free(camHal); |
| } |
| rc = 0; |
| } |
| |
| pthread_mutex_unlock(&camera_session_lock); |
| return rc; |
| } |
| |
| |
| int set_preview_window(struct camera_device * device, |
| struct preview_stream_ops *window) |
| { |
| int rc = -1; |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| |
| if(hardware != NULL) { |
| rc = hardware->setPreviewWindow(window); |
| } |
| return rc; |
| } |
| |
| void set_CallBacks(struct camera_device * device, |
| camera_notify_callback notify_cb, |
| camera_data_callback data_cb, |
| camera_data_timestamp_callback data_cb_timestamp, |
| camera_request_memory get_memory, |
| void *user) |
| { |
| ALOGV("Q%s: E", __func__); |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| hardware->setCallbacks(notify_cb,data_cb, data_cb_timestamp, get_memory, user); |
| } |
| } |
| |
| void enable_msg_type(struct camera_device * device, int32_t msg_type) |
| { |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| hardware->enableMsgType(msg_type); |
| } |
| } |
| |
| void disable_msg_type(struct camera_device * device, int32_t msg_type) |
| { |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| ALOGV("Q%s: E", __func__); |
| if(hardware != NULL){ |
| hardware->disableMsgType(msg_type); |
| } |
| } |
| |
| int msg_type_enabled(struct camera_device * device, int32_t msg_type) |
| { |
| ALOGV("Q%s: E", __func__); |
| int rc = -1; |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| rc = hardware->msgTypeEnabled(msg_type); |
| } |
| return rc; |
| } |
| |
| int start_preview(struct camera_device * device) |
| { |
| ALOGV("Q%s: E", __func__); |
| int rc = -1; |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| rc = hardware->startPreview( ); |
| } |
| ALOGV("Q%s: X", __func__); |
| return rc; |
| } |
| |
| void stop_preview(struct camera_device * device) |
| { |
| ALOGV("Q%s: E", __func__); |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| hardware->stopPreview( ); |
| } |
| } |
| |
| int preview_enabled(struct camera_device * device) |
| { |
| ALOGV("Q%s: E", __func__); |
| int rc = -1; |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| rc = hardware->previewEnabled( ); |
| } |
| return rc; |
| } |
| |
| int store_meta_data_in_buffers(struct camera_device * device, int enable) |
| { |
| ALOGV("Q%s: E", __func__); |
| int rc = -1; |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| rc = hardware->storeMetaDataInBuffers(enable); |
| } |
| return rc; |
| } |
| |
| int start_recording(struct camera_device * device) |
| { |
| ALOGV("Q%s: E", __func__); |
| int rc = -1; |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| rc = hardware->startRecording( ); |
| } |
| return rc; |
| } |
| |
| void stop_recording(struct camera_device * device) |
| { |
| ALOGV("Q%s: E", __func__); |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| hardware->stopRecording( ); |
| } |
| } |
| |
| int recording_enabled(struct camera_device * device) |
| { |
| ALOGV("Q%s: E", __func__); |
| int rc = -1; |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| rc = hardware->recordingEnabled( ); |
| } |
| return rc; |
| } |
| |
| void release_recording_frame(struct camera_device * device, |
| const void *opaque) |
| { |
| ALOGV("Q%s: E", __func__); |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| hardware->releaseRecordingFrame(opaque); |
| } |
| } |
| |
| int auto_focus(struct camera_device * device) |
| { |
| ALOGV("Q%s: E", __func__); |
| int rc = -1; |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| rc = hardware->autoFocus( ); |
| } |
| return rc; |
| } |
| |
| int cancel_auto_focus(struct camera_device * device) |
| { |
| ALOGV("Q%s: E", __func__); |
| int rc = -1; |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| rc = hardware->cancelAutoFocus( ); |
| } |
| return rc; |
| } |
| |
| int take_picture(struct camera_device * device) |
| { |
| ALOGV("Q%s: E", __func__); |
| int rc = -1; |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| rc = hardware->takePicture( ); |
| } |
| return rc; |
| } |
| |
| int cancel_picture(struct camera_device * device) |
| |
| { |
| ALOGV("Q%s: E", __func__); |
| int rc = -1; |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| rc = hardware->cancelPicture( ); |
| } |
| return rc; |
| } |
| |
| int set_parameters(struct camera_device * device, const char *parms) |
| |
| { |
| ALOGV("Q%s: E", __func__); |
| int rc = -1; |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL && parms){ |
| //QCameraParameters param;// = util_get_HAL_parameter(device); |
| //String8 str = String8(parms); |
| |
| //param.unflatten(str); |
| rc = hardware->setParameters(parms); |
| //rc = 0; |
| } |
| return rc; |
| } |
| |
| char* get_parameters(struct camera_device * device) |
| { |
| ALOGV("Q%s: E", __func__); |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| char *parms = NULL; |
| hardware->getParameters(&parms); |
| return parms; |
| } |
| return NULL; |
| } |
| |
| void put_parameters(struct camera_device * device, char *parm) |
| |
| { |
| ALOGV("Q%s: E", __func__); |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| hardware->putParameters(parm); |
| } |
| } |
| |
| int send_command(struct camera_device * device, |
| int32_t cmd, int32_t arg1, int32_t arg2) |
| { |
| ALOGV("Q%s: E", __func__); |
| int rc = -1; |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| rc = hardware->sendCommand( cmd, arg1, arg2); |
| } |
| return rc; |
| } |
| |
| void release(struct camera_device * device) |
| { |
| ALOGV("Q%s: E", __func__); |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| camera_hardware_t *camHal = (camera_hardware_t *)device->priv; |
| hardware->release( ); |
| camHal->camera_released = true; |
| } |
| } |
| |
| int dump(struct camera_device * device, int fd) |
| { |
| ALOGV("Q%s: E", __func__); |
| int rc = -1; |
| QCameraHardwareInterface *hardware = util_get_Hal_obj(device); |
| if(hardware != NULL){ |
| rc = hardware->dump( fd ); |
| //rc = 0; |
| } |
| return rc; |
| } |
| |
| }; // namespace android |