Permalink
Browse files

Fix a whole bunch of things

Support for multiple cameras.
Add software decoding support
Fix barcode scanners memory leak
Fix 30sec video recording limit issue caused by memory leak
Add support for HWA ROMs (tested only on HD2)
  • Loading branch information...
1 parent d076eb6 commit 903d325fc65b220902a476be260a387117f30f32 @rapmv78 committed May 4, 2012
Showing with 977 additions and 20 deletions.
  1. +2 −2 Android.mk
  2. +162 −18 cameraHal.cpp
  3. +813 −0 cameraHal.cpp.orig
View
@@ -17,8 +17,8 @@ CAMERA_LIB := camera-nexus
endif
TARGET_GLOBAL_LD_DIRS += -L$(LOCAL_PATH) -l${CAMERA_LIB}
-LOCAL_SHARED_LIBRARIES := liblog libdl libutils libcamera_client libbinder libcutils libhardware
+LOCAL_SHARED_LIBRARIES := liblog libdl libutils libcamera_client libbinder libcutils libhardware libui
LOCAL_C_INCLUDES := frameworks/base/services/ frameworks/base/include
-LOCAL_C_INCLUDES += hardware/libhardware/include/ hardware/libhardware/modules/gralloc/
+LOCAL_C_INCLUDES += hardware/libhardware/include/ hardware
include $(BUILD_SHARED_LIBRARY)
View
@@ -23,11 +23,21 @@
#include <fcntl.h>
#include <linux/ioctl.h>
#include <linux/msm_mdp.h>
-#include <gralloc_priv.h>
+#include <ui/Rect.h>
+#include <ui/GraphicBufferMapper.h>
+#include <dlfcn.h>
#define NO_ERROR 0
-//#define LOGV LOGI
#define GRALLOC_USAGE_PMEM_PRIVATE_ADSP GRALLOC_USAGE_PRIVATE_0
+#define MSM_COPY_HW 1
+#define HWA 1
+#ifdef HWA
+#include "qcom/display/libgralloc/gralloc_priv.h"
+#else
+#include "libhardware/modules/gralloc/gralloc_priv.h"
+#endif
+
+//#define LOGV LOGI
struct qcom_mdp_rect {
uint32_t x;
@@ -60,7 +70,9 @@ struct blitreq {
};
/* Prototypes and extern functions. */
-extern "C" android::sp<android::CameraHardwareInterface> openCameraHardware(int id);
+android::sp<android::CameraHardwareInterface> (*LINK_openCameraHardware)(int id);
+int (*LINK_getNumberofCameras)(void);
+void (*LINK_getCameraInfo)(int cameraId, struct camera_info *info);
int qcamera_device_open(const hw_module_t* module, const char* name,
hw_device_t** device);
int CameraHAL_GetNum_Cameras(void);
@@ -109,18 +121,23 @@ CameraHAL_NotifyCb(int32_t msg_type, int32_t ext1,
}
}
-void
+bool
CameraHAL_CopyBuffers_Hw(int srcFd, int destFd,
size_t srcOffset, size_t destOffset,
int srcFormat, int destFormat,
int x, int y, int w, int h)
{
struct blitreq blit;
+ bool success = true;
int fb_fd = open("/dev/graphics/fb0", O_RDWR);
+#ifndef MSM_COPY_HW
+ return false;
+#endif
+
if (fb_fd < 0) {
LOGD("CameraHAL_CopyBuffers_Hw: Error opening /dev/graphics/fb0\n");
- return;
+ return false;
}
LOGV("CameraHAL_CopyBuffers_Hw: srcFD:%d destFD:%d srcOffset:%#x"
@@ -152,12 +169,48 @@ CameraHAL_CopyBuffers_Hw(int srcFd, int destFd,
blit.req.src_rect.h = blit.req.dst_rect.h = h;
if (ioctl(fb_fd, MSMFB_BLIT, &blit)) {
- LOGE("CameraHAL_CopyBuffers_Hw: MSMFB_BLIT failed = %d %s\n",
+ LOGV("CameraHAL_CopyBuffers_Hw: MSMFB_BLIT failed = %d %s\n",
errno, strerror(errno));
+ success = false;
}
close(fb_fd);
+ return success;
}
+void
+CameraHal_Decode_Sw(unsigned int* rgb, char* yuv420sp, int width, int height)
+{
+ int frameSize = width * height;
+
+ if (!qCamera->previewEnabled()) return;
+
+ for (int j = 0, yp = 0; j < height; j++) {
+ int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
+ for (int i = 0; i < width; i++, yp++) {
+ int y = (0xff & ((int) yuv420sp[yp])) - 16;
+ if (y < 0) y = 0;
+ if ((i & 1) == 0) {
+ v = (0xff & yuv420sp[uvp++]) - 128;
+ u = (0xff & yuv420sp[uvp++]) - 128;
+ }
+
+ int y1192 = 1192 * y;
+ int r = (y1192 + 1634 * v);
+ int g = (y1192 - 833 * v - 400 * u);
+ int b = (y1192 + 2066 * u);
+
+ if (r < 0) r = 0; else if (r > 262143) r = 262143;
+ if (g < 0) g = 0; else if (g > 262143) g = 262143;
+ if (b < 0) b = 0; else if (b > 262143) b = 262143;
+
+ rgb[yp] = 0xff000000 | ((b << 6) & 0xff0000) |
+ ((g >> 2) & 0xff00) | ((r >> 10) & 0xff);
+ }
+ }
+}
+
+
+
void
CameraHAL_CopyBuffers_Sw(char *dest, char *src, int size)
{
@@ -184,7 +237,7 @@ CameraHAL_CopyBuffers_Sw(char *dest, char *src, int size)
}
void
-CameraHAL_HandlePreviewData(const android::sp<android::IMemory>& dataPtr,
+CameraHAL_HandlePreviewData(const android::sp<android::IMemory>& dataPtr,
preview_stream_ops_t *mWindow,
camera_request_memory getMemory,
int32_t previewWidth, int32_t previewHeight)
@@ -193,7 +246,11 @@ CameraHAL_HandlePreviewData(const android::sp<android::IMemory>& dataPtr,
ssize_t offset;
size_t size;
int32_t previewFormat = MDP_Y_CBCR_H2V2;
+#ifdef HWA
+ int32_t destFormat = MDP_RGBX_8888;
+#else
int32_t destFormat = MDP_RGBA_8888;
+#endif
android::status_t retVal;
android::sp<android::IMemoryHeap> mHeap = dataPtr->getMemory(&offset,
@@ -204,11 +261,18 @@ CameraHAL_HandlePreviewData(const android::sp<android::IMemory>& dataPtr,
(unsigned)offset, size, mHeap != NULL ? mHeap->base() : 0);
mWindow->set_usage(mWindow,
+#ifndef HWA
GRALLOC_USAGE_PMEM_PRIVATE_ADSP |
+#endif
GRALLOC_USAGE_SW_READ_OFTEN);
retVal = mWindow->set_buffers_geometry(mWindow,
previewWidth, previewHeight,
- HAL_PIXEL_FORMAT_RGBA_8888);
+#ifdef HWA
+ HAL_PIXEL_FORMAT_RGBX_8888
+#else
+ HAL_PIXEL_FORMAT_RGBA_8888
+#endif
+ );
if (retVal == NO_ERROR) {
int32_t stride;
buffer_handle_t *bufHandle = NULL;
@@ -220,10 +284,32 @@ CameraHAL_HandlePreviewData(const android::sp<android::IMemory>& dataPtr,
if (retVal == NO_ERROR) {
private_handle_t const *privHandle =
reinterpret_cast<private_handle_t const *>(*bufHandle);
- CameraHAL_CopyBuffers_Hw(mHeap->getHeapID(), privHandle->fd,
- offset, privHandle->offset,
- previewFormat, destFormat,
- 0, 0, previewWidth, previewHeight);
+ if (!CameraHAL_CopyBuffers_Hw(mHeap->getHeapID(), privHandle->fd,
+ offset, privHandle->offset,
+ previewFormat, destFormat,
+ 0, 0, previewWidth,
+ previewHeight)) {
+ void *bits;
+ android::Rect bounds;
+ android::GraphicBufferMapper &mapper =
+ android::GraphicBufferMapper::get();
+
+ bounds.left = 0;
+ bounds.top = 0;
+ bounds.right = previewWidth;
+ bounds.bottom = previewHeight;
+
+ mapper.lock(*bufHandle, GRALLOC_USAGE_SW_READ_OFTEN, bounds,
+ &bits);
+ LOGV("CameraHAL_HPD: w:%d h:%d bits:%p",
+ previewWidth, previewHeight, bits);
+ CameraHal_Decode_Sw((unsigned int *)bits, (char *)mHeap->base() + offset,
+ previewWidth, previewHeight);
+
+ // unlock buffer before sending to display
+ mapper.unlock(*bufHandle);
+ }
+
mWindow->enqueue_buffer(mWindow, bufHandle);
LOGV("CameraHAL_HandlePreviewData: enqueued buffer\n");
} else {
@@ -252,7 +338,7 @@ CameraHAL_GenClientData(const android::sp<android::IMemory> &dataPtr,
clientData = reqClientMemory(-1, size, 1, user);
if (clientData != NULL) {
- CameraHAL_CopyBuffers_Sw((char *)clientData->data,
+ CameraHAL_CopyBuffers_Sw((char *)clientData->data,
(char *)(mHeap->base()) + offset, size);
} else {
LOGV("CameraHAL_GenClientData: ERROR allocating memory from client\n");
@@ -272,12 +358,14 @@ CameraHAL_DataCb(int32_t msg_type, const android::sp<android::IMemory>& dataPtr,
CameraHAL_HandlePreviewData(dataPtr, mWindow, origCamReqMemory,
previewWidth, previewHeight);
}
+
if (origData_cb != NULL && origCamReqMemory != NULL) {
camera_memory_t *clientData = CameraHAL_GenClientData(dataPtr,
origCamReqMemory, user);
if (clientData != NULL) {
LOGV("CameraHAL_DataCb: Posting data to client\n");
origData_cb(msg_type, clientData, 0, NULL, user);
+ clientData->release(clientData);
}
}
}
@@ -297,6 +385,7 @@ CameraHAL_DataTSCb(nsecs_t timestamp, int32_t msg_type,
systemTime());
origDataTS_cb(timestamp, msg_type, clientData, 0, user);
qCamera->releaseRecordingFrame(dataPtr);
+ clientData->release(clientData);
} else {
LOGD("CameraHAL_DataTSCb: ERROR allocating memory from client\n");
}
@@ -306,16 +395,48 @@ CameraHAL_DataTSCb(nsecs_t timestamp, int32_t msg_type,
int
CameraHAL_GetNum_Cameras(void)
{
+ int numCameras = 1;
+
LOGE("CameraHAL_GetNum_Cameras:\n");
- return 1;
+ void *libcameraHandle = ::dlopen("libcamera.so", RTLD_NOW);
+ LOGD("CameraHAL_GetNum_Cameras: loading libcamera at %p", libcameraHandle);
+ if (!libcameraHandle) {
+ LOGE("FATAL ERROR: could not dlopen libcamera.so: %s", dlerror());
+ } else {
+ if (::dlsym(libcameraHandle, "HAL_getNumberOfCameras") != NULL) {
+ *(void**)&LINK_getNumberofCameras =
+ ::dlsym(libcameraHandle, "HAL_getNumberOfCameras");
+ numCameras = LINK_getNumberofCameras();
+ LOGD("CameraHAL_GetNum_Cameras: numCameras:%d", numCameras);
+ }
+ dlclose(libcameraHandle);
+ }
+ return numCameras;
}
int
CameraHAL_GetCam_Info(int camera_id, struct camera_info *info)
{
+ bool dynamic = false;
LOGV("CameraHAL_GetCam_Info:\n");
- info->facing = CAMERA_FACING_BACK;
- info->orientation = 90;
+ void *libcameraHandle = ::dlopen("libcamera.so", RTLD_NOW);
+ LOGD("CameraHAL_GetNum_Cameras: loading libcamera at %p", libcameraHandle);
+ if (!libcameraHandle) {
+ LOGE("FATAL ERROR: could not dlopen libcamera.so: %s", dlerror());
+ return EINVAL;
+ } else {
+ if (::dlsym(libcameraHandle, "HAL_getCameraInfo") != NULL) {
+ *(void**)&LINK_getCameraInfo =
+ ::dlsym(libcameraHandle, "HAL_getCameraInfo");
+ LINK_getCameraInfo(camera_id, info);
+ dynamic = true;
+ }
+ dlclose(libcameraHandle);
+ }
+ if (!dynamic) {
+ info->facing = CAMERA_FACING_BACK;
+ info->orientation = 90;
+ }
return NO_ERROR;
}
@@ -593,7 +714,7 @@ qcamera_send_command(struct camera_device * device, int32_t cmd,
{
LOGV("qcamera_send_command: cmd:%d arg0:%d arg1:%d\n",
cmd, arg0, arg1);
- return NO_ERROR;
+ return qCamera->sendCommand(cmd, arg0, arg1);
}
void
@@ -631,17 +752,40 @@ camera_device_close(hw_device_t* device)
return rc;
}
+
int
qcamera_device_open(const hw_module_t* module, const char* name,
hw_device_t** device)
{
+ void *libcameraHandle;
int cameraId = atoi(name);
LOGD("qcamera_device_open: name:%s device:%p cameraId:%d\n",
name, device, cameraId);
- qCamera = openCameraHardware(cameraId);
+ libcameraHandle = ::dlopen("libcamera.so", RTLD_NOW);
+ LOGD("loading libcamera at %p", libcameraHandle);
+ if (!libcameraHandle) {
+ LOGE("FATAL ERROR: could not dlopen libcamera.so: %s", dlerror());
+ return false;
+ }
+
+ if (::dlsym(libcameraHandle, "openCameraHardware") != NULL) {
+ *(void**)&LINK_openCameraHardware =
+ ::dlsym(libcameraHandle, "openCameraHardware");
+ } else if (::dlsym(libcameraHandle, "HAL_openCameraHardware") != NULL) {
+ *(void**)&LINK_openCameraHardware =
+ ::dlsym(libcameraHandle, "HAL_openCameraHardware");
+ } else {
+ LOGE("FATAL ERROR: Could not find openCameraHardware");
+ dlclose(libcameraHandle);
+ return false;
+ }
+
+ qCamera = LINK_openCameraHardware(cameraId);
+ ::dlclose(libcameraHandle);
+
camera_device_t* camera_device = NULL;
camera_device_ops_t* camera_ops = NULL;
Oops, something went wrong.

0 comments on commit 903d325

Please sign in to comment.