summaryrefslogtreecommitdiffstats
path: root/libcamera
diff options
context:
space:
mode:
Diffstat (limited to 'libcamera')
-rw-r--r--libcamera/Android.mk29
-rwxr-xr-xlibcamera/SecCamera.cpp122
-rw-r--r--libcamera/SecCamera.h21
-rwxr-xr-x[-rw-r--r--]libcamera/SecCameraHWInterface.cpp1255
-rw-r--r--libcamera/SecCameraHWInterface.h82
5 files changed, 956 insertions, 553 deletions
diff --git a/libcamera/Android.mk b/libcamera/Android.mk
index 79f4e3c..1ade091 100644
--- a/libcamera/Android.mk
+++ b/libcamera/Android.mk
@@ -1,42 +1,25 @@
ifneq ($(filter crespo crespo4g,$(TARGET_DEVICE)),)
-# When zero we link against libqcamera; when 1, we dlopen libqcamera.
-ifeq ($(BOARD_CAMERA_LIBRARIES),libcamera)
-
-DLOPEN_LIBSECCAMERA:=1
-
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_CFLAGS:=-fno-short-enums
-LOCAL_CFLAGS+=-DDLOPEN_LIBSECCAMERA=$(DLOPEN_LIBSECCAMERA)
+# HAL module implemenation stored in
+# hw/<COPYPIX_HARDWARE_MODULE_ID>.<ro.product.board>.so
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../libs3cjpeg
-
LOCAL_SRC_FILES:= \
- SecCamera.cpp \
- SecCameraHWInterface.cpp
+ SecCamera.cpp SecCameraHWInterface.cpp
-
-LOCAL_SHARED_LIBRARIES:= libutils libui liblog libbinder libcutils
+LOCAL_SHARED_LIBRARIES:= libutils libcutils libbinder liblog libcamera_client libhardware
LOCAL_SHARED_LIBRARIES+= libs3cjpeg
-LOCAL_SHARED_LIBRARIES+= libcamera_client
-ifeq ($(BOARD_USES_OVERLAY),true)
-LOCAL_CFLAGS += -DBOARD_USES_OVERLAY
-endif
-
-ifeq ($(DLOPEN_LIBSECCAMERA),1)
-LOCAL_SHARED_LIBRARIES+= libdl
-endif
-
-LOCAL_MODULE:= libcamera
+LOCAL_MODULE := camera.herring
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
endif
-endif
diff --git a/libcamera/SecCamera.cpp b/libcamera/SecCamera.cpp
index 4d0705a..48cf02e 100755
--- a/libcamera/SecCamera.cpp
+++ b/libcamera/SecCamera.cpp
@@ -122,24 +122,6 @@ static int get_pixel_depth(unsigned int fmt)
#define ALIGN_H(x) (((x) + 0x1F) & (~0x1F)) // Set as multiple of 32
#define ALIGN_BUF(x) (((x) + 0x1FFF)& (~0x1FFF)) // Set as multiple of 8K
-static int init_preview_buffers(struct fimc_buffer *buffers, int width, int height, unsigned int fmt)
-{
- int i, len;
-
- if (fmt==V4L2_PIX_FMT_NV12T) {
- len = ALIGN_BUF(ALIGN_W(width) * ALIGN_H(height)) +
- ALIGN_BUF(ALIGN_W(width) * ALIGN_H(height / 2));
- } else {
- len = (width * height * get_pixel_depth(fmt)) / 8;
- }
-
- for (i = 0; i < MAX_BUFFERS; i++) {
- buffers[i].length = len;
- }
-
- return 0;
-}
-
static int fimc_poll(struct pollfd *events)
{
int ret;
@@ -546,6 +528,8 @@ static int fimc_v4l2_s_parm(int fp, struct v4l2_streamparm *streamparm)
SecCamera::SecCamera() :
m_flag_init(0),
m_camera_id(CAMERA_ID_BACK),
+ m_cam_fd(-1),
+ m_cam_fd2(-1),
m_preview_v4lformat(V4L2_PIX_FMT_NV21),
m_preview_width (0),
m_preview_height (0),
@@ -609,12 +593,6 @@ SecCamera::SecCamera() :
LOGV("%s :", __func__);
}
-int SecCamera::flagCreate(void) const
-{
- LOGV("%s : : %d", __func__, m_flag_init);
- return m_flag_init;
-}
-
SecCamera::~SecCamera()
{
LOGV("%s :", __func__);
@@ -632,43 +610,12 @@ int SecCamera::initCamera(int index)
*/
m_camera_af_flag = -1;
- m_cam_fd_temp = -1;
- m_cam_fd2_temp = -1;
-
m_cam_fd = open(CAMERA_DEV_NAME, O_RDWR);
if (m_cam_fd < 0) {
LOGE("ERR(%s):Cannot open %s (error : %s)\n", __func__, CAMERA_DEV_NAME, strerror(errno));
return -1;
}
-
- if (m_cam_fd < 3) { // for 0, 1, 2
- LOGE("ERR(%s):m_cam_fd is %d\n", __func__, m_cam_fd);
-
- close(m_cam_fd);
-
- m_cam_fd_temp = open(CAMERA_DEV_NAME_TEMP, O_CREAT);
-
- LOGE("ERR(%s):m_cam_fd_temp is %d\n", __func__, m_cam_fd_temp);
-
- m_cam_fd = open(CAMERA_DEV_NAME, O_RDWR);
-
- if (m_cam_fd < 3) { // for 0, 1, 2
- LOGE("ERR(%s):retring to open %s is failed, %d\n", __func__, CAMERA_DEV_NAME, m_cam_fd);
-
- if (m_cam_fd < 0) {
- return -1;
- } else {
- close(m_cam_fd);
- m_cam_fd = -1;
- }
-
- if (m_cam_fd_temp != -1){
- close(m_cam_fd_temp);
- m_cam_fd_temp = -1;
- }
- return -1;
- }
- }
+ LOGV("%s: open(%s) --> m_cam_fd %d", __FUNCTION__, CAMERA_DEV_NAME, m_cam_fd);
LOGE("initCamera: m_cam_fd(%d), m_jpeg_fd(%d)", m_cam_fd, m_jpeg_fd);
@@ -680,50 +627,11 @@ int SecCamera::initCamera(int index)
CHECK(ret);
m_cam_fd2 = open(CAMERA_DEV_NAME2, O_RDWR);
+ LOGV("%s: open(%s) --> m_cam_fd2 = %d", __FUNCTION__, CAMERA_DEV_NAME2, m_cam_fd2);
if (m_cam_fd2 < 0) {
LOGE("ERR(%s):Cannot open %s (error : %s)\n", __func__, CAMERA_DEV_NAME2, strerror(errno));
return -1;
}
- if (m_cam_fd2 < 3) { // for 0, 1, 2
- LOGE("ERR(%s):m_cam_fd2 is %d\n", __func__, m_cam_fd2);
-
- close(m_cam_fd2);
-
- m_cam_fd2_temp = open(CAMERA_DEV_NAME2_TEMP, O_CREAT);
-
- LOGE("ERR(%s):m_cam_fd2_temp is %d\n", __func__, m_cam_fd2_temp);
-
- m_cam_fd2 = open(CAMERA_DEV_NAME2, O_RDWR);
-
- if (m_cam_fd2 < 3) { // for 0, 1, 2
- LOGE("ERR(%s):retring to open %s is failed, %d\n", __func__, CAMERA_DEV_NAME2, m_cam_fd2);
-
- if (m_cam_fd2 < 0) {
- return -1;
- }
- else{
- close(m_cam_fd2);
- m_cam_fd2 = -1;
- }
-
- if (m_cam_fd2_temp != -1) {
- close(m_cam_fd2_temp);
- m_cam_fd2_temp = -1;
- }
-
- return -1;
- }
- }
-
- if (m_cam_fd_temp != -1) {
- close(m_cam_fd_temp);
- m_cam_fd_temp = -1;
- }
-
- if (m_cam_fd2_temp != -1) {
- close(m_cam_fd2_temp);
- m_cam_fd2_temp = -1;
- }
LOGE("initCamera: m_cam_fd2(%d)", m_cam_fd2);
@@ -755,6 +663,7 @@ int SecCamera::initCamera(int index)
setExifFixedAttribute();
m_flag_init = 1;
+ LOGI("%s : initialized", __FUNCTION__);
}
return 0;
}
@@ -789,18 +698,9 @@ void SecCamera::DeinitCamera()
m_cam_fd2 = -1;
}
- if (m_cam_fd_temp != -1) {
- close(m_cam_fd_temp);
- m_cam_fd_temp = -1;
- }
-
- if (m_cam_fd2_temp != -1) {
- close(m_cam_fd2_temp);
- m_cam_fd2_temp = -1;
- }
-
m_flag_init = 0;
}
+ else LOGI("%s : already deinitialized", __FUNCTION__);
}
@@ -1527,7 +1427,7 @@ int SecCamera::getSnapshotAndJpeg(unsigned char *yuv_buf, unsigned char *jpeg_bu
memcpy(pInBuf, yuv_buf, snapshot_size);
setExifChangedAttribute();
- jpgEnc.encode(output_size, &mExifInfo);
+ jpgEnc.encode(output_size, NULL);
uint64_t outbuf_size;
unsigned char *pOutBuf = (unsigned char *)jpgEnc.getOutBuf(&outbuf_size);
@@ -2746,9 +2646,7 @@ int SecCamera::setDataLineCheck(int chk_dataline)
return -1;
}
- if (m_chk_dataline != chk_dataline) {
- m_chk_dataline = chk_dataline;
- }
+ m_chk_dataline = chk_dataline;
return 0;
}
@@ -3124,7 +3022,7 @@ inline int SecCamera::m_frameSize(int format, int width, int height)
return size;
}
-status_t SecCamera::dump(int fd, const Vector<String16> &args)
+status_t SecCamera::dump(int fd)
{
const size_t SIZE = 256;
char buffer[SIZE];
@@ -3136,7 +3034,7 @@ status_t SecCamera::dump(int fd, const Vector<String16> &args)
}
double SecCamera::jpeg_ratio = 0.7;
-int SecCamera::interleaveDataSize = 4261248;
+int SecCamera::interleaveDataSize = 5242880;
int SecCamera::jpegLineLength = 636;
}; // namespace android
diff --git a/libcamera/SecCamera.h b/libcamera/SecCamera.h
index c87a0f4..551eb03 100644
--- a/libcamera/SecCamera.h
+++ b/libcamera/SecCamera.h
@@ -33,12 +33,13 @@
#include <sys/poll.h>
#include <sys/stat.h>
+#include <utils/RefBase.h>
#include <linux/videodev2.h>
#include <videodev2_samsung.h>
-#include "JpegEncoder.h"
+#include <utils/String8.h>
-#include <camera/CameraHardwareInterface.h>
+#include "JpegEncoder.h"
namespace android {
@@ -144,8 +145,7 @@ namespace android {
#define BPP 2
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
-#define MAX_BUFFERS 11
-
+#define MAX_BUFFERS 9 // 11
/*
* V 4 L 2 F I M C E X T E N S I O N S
*
@@ -200,8 +200,7 @@ struct camsensor_date_info {
unsigned int date;
};
-
-class SecCamera {
+class SecCamera : public virtual RefBase {
public:
enum CAMERA_ID {
@@ -272,17 +271,14 @@ public:
} gpsInfoAltitude;
SecCamera();
- ~SecCamera();
+ virtual ~SecCamera();
static SecCamera* createInstance(void)
{
static SecCamera singleton;
return &singleton;
}
- status_t dump(int fd, const Vector<String16>& args);
-
- int flagCreate(void) const;
-
+ status_t dump(int fd);
int getCameraId(void);
@@ -490,9 +486,6 @@ private:
int m_cam_fd;
- int m_cam_fd_temp;
- int m_cam_fd2_temp;
-
int m_cam_fd2;
struct pollfd m_events_c2;
int m_flag_record_start;
diff --git a/libcamera/SecCameraHWInterface.cpp b/libcamera/SecCameraHWInterface.cpp
index 8ca648c..875fbcd 100644..100755
--- a/libcamera/SecCameraHWInterface.cpp
+++ b/libcamera/SecCameraHWInterface.cpp
@@ -24,13 +24,8 @@
#include <utils/threads.h>
#include <fcntl.h>
#include <sys/mman.h>
-
-#if defined(BOARD_USES_OVERLAY)
-#include <hardware/overlay.h>
-#include <ui/Overlay.h>
-#define CACHEABLE_BUFFERS 0x1
-#define ALL_BUFFERS_FLUSHED -66
-#endif
+#include <camera/Camera.h>
+#include <media/stagefright/MetadataBufferType.h>
#define VIDEO_COMMENT_MARKER_H 0xFFBE
#define VIDEO_COMMENT_MARKER_L 0xFFBF
@@ -44,9 +39,23 @@
#define BACK_CAMERA_INFINITY_FOCUS_DISTANCES_STR "0.10,1.20,Infinity"
#define FRONT_CAMERA_FOCUS_DISTANCES_STR "0.20,0.25,Infinity"
+// FIXME:
+// -- The actual preview color is set to YV12. The preview frames
+// returned via preview callback must be generated by color
+// conversion if the requested preview color format for the
+// preview frames is _not_ YV12. The reason that YV12 is used
+// for actual preview is because that is the only color format
+// supported by gralloc. Matching the preview cor format with
+// gralloc color format improves performance since no color
+// conversion is needed for preview.
+//
+// -- we only support two preview color formats that client
+// applications can set: NV21 and YUV420/YV12.
+
namespace android {
struct addrs {
+ uint32_t type; // make sure that this is 4 byte.
unsigned int addr_y;
unsigned int addr_cbcr;
unsigned int buf_index;
@@ -62,21 +71,15 @@ struct addrs_cap {
static const int INITIAL_SKIP_FRAME = 3;
static const int EFFECT_SKIP_FRAME = 1;
-CameraHardwareSec::CameraHardwareSec(int cameraId)
+gralloc_module_t const* CameraHardwareSec::mGrallocHal;
+
+CameraHardwareSec::CameraHardwareSec(int cameraId, camera_device_t *dev)
:
mCaptureInProgress(false),
mParameters(),
- mPreviewHeap(0),
- mRawHeap(0),
- mRecordHeap(0),
- mJpegHeap(0),
- mSecCamera(NULL),
+ mFrameSizeDelta(0),
mCameraSensorName(NULL),
mSkipFrame(0),
-#if defined(BOARD_USES_OVERLAY)
- mUseOverlay(false),
- mOverlayBufferIdx(0),
-#endif
mNotifyCb(0),
mDataCb(0),
mDataCbTimestamp(0),
@@ -85,15 +88,23 @@ CameraHardwareSec::CameraHardwareSec(int cameraId)
mRecordRunning(false),
mPostViewWidth(0),
mPostViewHeight(0),
- mPostViewSize(0)
+ mPostViewSize(0),
+ mHalDevice(dev)
{
LOGV("%s :", __func__);
int ret = 0;
+ mPreviewWindow = NULL;
mSecCamera = SecCamera::createInstance();
- if (mSecCamera == NULL) {
- LOGE("ERR(%s):Fail on mSecCamera object creation", __func__);
+ mRawHeap = NULL;
+ mPreviewHeap = NULL;
+ mRecordHeap = NULL;
+
+ if (!mGrallocHal) {
+ ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&mGrallocHal);
+ if (ret)
+ LOGE("ERR(%s):Fail on loading gralloc HAL", __func__);
}
ret = mSecCamera->initCamera(cameraId);
@@ -101,30 +112,10 @@ CameraHardwareSec::CameraHardwareSec(int cameraId)
LOGE("ERR(%s):Fail on mSecCamera init", __func__);
}
- if (mSecCamera->flagCreate() == 0) {
- LOGE("ERR(%s):Fail on mSecCamera->flagCreate()", __func__);
- }
-
- int recordHeapSize = sizeof(struct addrs) * kBufferCount;
- LOGV("mRecordHeap : MemoryHeapBase(recordHeapSize(%d))", recordHeapSize);
- mRecordHeap = new MemoryHeapBase(recordHeapSize);
- if (mRecordHeap->getHeapID() < 0) {
- LOGE("ERR(%s): Record heap creation fail", __func__);
- mRecordHeap.clear();
- }
-
mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize);
LOGV("mPostViewWidth = %d mPostViewHeight = %d mPostViewSize = %d",
mPostViewWidth,mPostViewHeight,mPostViewSize);
- int rawHeapSize = mPostViewSize;
- LOGV("mRawHeap : MemoryHeapBase(previewHeapSize(%d))", rawHeapSize);
- mRawHeap = new MemoryHeapBase(rawHeapSize);
- if (mRawHeap->getHeapID() < 0) {
- LOGE("ERR(%s): Raw heap creation fail", __func__);
- mRawHeap.clear();
- }
-
initDefaultParameters(cameraId);
mExitAutoFocusThread = false;
@@ -133,11 +124,17 @@ CameraHardwareSec::CameraHardwareSec(int cameraId)
* create the thread but it is initially in stopped state.
*/
mPreviewRunning = false;
+ mPreviewStartDeferred = false;
mPreviewThread = new PreviewThread(this);
mAutoFocusThread = new AutoFocusThread(this);
mPictureThread = new PictureThread(this);
}
+int CameraHardwareSec::getCameraId() const
+{
+ return mSecCamera->getCameraId();
+}
+
void CameraHardwareSec::initDefaultParameters(int cameraId)
{
if (mSecCamera == NULL) {
@@ -180,20 +177,20 @@ void CameraHardwareSec::initDefaultParameters(int cameraId)
&snapshot_max_height) < 0)
LOGE("getSnapshotMaxSize fail (%d / %d) \n",
snapshot_max_width, snapshot_max_height);
-
- p.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP);
+ String8 previewColorString;
+ previewColorString = CameraParameters::PIXEL_FORMAT_YUV420SP;
+ previewColorString.append(",");
+ previewColorString.append(CameraParameters::PIXEL_FORMAT_YUV420P);
+ p.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP); mFrameSizeDelta = 16;
+ p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, previewColorString.string());
+ p.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT, CameraParameters::PIXEL_FORMAT_YUV420P);
p.setPreviewSize(preview_max_width, preview_max_height);
p.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
p.setPictureSize(snapshot_max_width, snapshot_max_height);
p.set(CameraParameters::KEY_JPEG_QUALITY, "100"); // maximum quality
-
- p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
- CameraParameters::PIXEL_FORMAT_YUV420SP);
p.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
CameraParameters::PIXEL_FORMAT_JPEG);
- p.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
- CameraParameters::PIXEL_FORMAT_YUV420SP);
String8 parameterString;
@@ -361,34 +358,90 @@ void CameraHardwareSec::initDefaultParameters(int cameraId)
CameraHardwareSec::~CameraHardwareSec()
{
- LOGV("%s :", __func__);
-
- singleton.clear();
+ LOGV("%s", __func__);
+ mSecCamera->DeinitCamera();
}
-status_t CameraHardwareSec::setPreviewWindow(const sp<ANativeWindow>& buf)
+status_t CameraHardwareSec::setPreviewWindow(preview_stream_ops *w)
{
- return NO_ERROR;
-}
+ int min_bufs;
-sp<IMemoryHeap> CameraHardwareSec::getPreviewHeap() const
-{
- return mPreviewHeap;
-}
+ mPreviewWindow = w;
+ LOGV("%s: mPreviewWindow %p", __func__, mPreviewWindow);
-sp<IMemoryHeap> CameraHardwareSec::getRawHeap() const
-{
- return mRawHeap;
+ if (!w) {
+ LOGE("preview window is NULL!");
+ return OK;
+ }
+
+ mPreviewLock.lock();
+
+ if (mPreviewRunning && !mPreviewStartDeferred) {
+ LOGI("stop preview (window change)");
+ stopPreviewInternal();
+ }
+
+ if (w->get_min_undequeued_buffer_count(w, &min_bufs)) {
+ LOGE("%s: could not retrieve min undequeued buffer count", __func__);
+ return INVALID_OPERATION;
+ }
+
+ if (min_bufs >= kBufferCount) {
+ LOGE("%s: min undequeued buffer count %d is too high (expecting at most %d)", __func__,
+ min_bufs, kBufferCount - 1);
+ }
+
+ LOGV("%s: setting buffer count to %d", __func__, kBufferCount);
+ if (w->set_buffer_count(w, kBufferCount)) {
+ LOGE("%s: could not set buffer count", __func__);
+ return INVALID_OPERATION;
+ }
+
+ int preview_width;
+ int preview_height;
+ mParameters.getPreviewSize(&preview_width, &preview_height);
+ int hal_pixel_format = HAL_PIXEL_FORMAT_YV12;
+
+ const char *str_preview_format = mParameters.getPreviewFormat();
+ LOGV("%s: preview format %s", __func__, str_preview_format);
+ mFrameSizeDelta = 16;
+
+ if (w->set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN)) {
+ LOGE("%s: could not set usage on gralloc buffer", __func__);
+ return INVALID_OPERATION;
+ }
+
+ if (w->set_buffers_geometry(w,
+ preview_width, preview_height,
+ hal_pixel_format)) {
+ LOGE("%s: could not set buffers geometry to %s",
+ __func__, str_preview_format);
+ return INVALID_OPERATION;
+ }
+
+ if (mPreviewRunning && mPreviewStartDeferred) {
+ LOGV("start/resume preview");
+ status_t ret = startPreviewInternal();
+ if (ret == OK) {
+ mPreviewStartDeferred = false;
+ mPreviewCondition.signal();
+ }
+ }
+ mPreviewLock.unlock();
+
+ return OK;
}
-void CameraHardwareSec::setCallbacks(notify_callback notify_cb,
- data_callback data_cb,
- data_callback_timestamp data_cb_timestamp,
- void *user)
+void CameraHardwareSec::setCallbacks(camera_notify_callback notify_cb,
+ camera_data_callback data_cb,
+ camera_data_timestamp_callback data_cb_timestamp,
+ camera_request_memory get_memory,
+ void *user)
{
mNotifyCb = notify_cb;
mDataCb = data_cb;
mDataCbTimestamp = data_cb_timestamp;
+ mGetMemoryCb = get_memory;
mCallbackCookie = user;
}
@@ -397,6 +450,7 @@ void CameraHardwareSec::enableMsgType(int32_t msgType)
LOGV("%s : msgType = 0x%x, mMsgEnabled before = 0x%x",
__func__, msgType, mMsgEnabled);
mMsgEnabled |= msgType;
+
LOGV("%s : mMsgEnabled = 0x%x", __func__, mMsgEnabled);
}
@@ -460,10 +514,14 @@ int CameraHardwareSec::previewThread()
LOGE("ERR(%s):Fail on SecCamera->getPreview()", __func__);
return UNKNOWN_ERROR;
}
+
+// LOGV("%s: index %d", __func__, index);
+
mSkipFrameLock.lock();
if (mSkipFrame > 0) {
mSkipFrame--;
mSkipFrameLock.unlock();
+ LOGV("%s: index %d skipping frame", __func__, index);
return NO_ERROR;
}
mSkipFrameLock.unlock();
@@ -474,7 +532,8 @@ int CameraHardwareSec::previewThread()
phyCAddr = mSecCamera->getPhyAddrC(index);
if (phyYAddr == 0xffffffff || phyCAddr == 0xffffffff) {
- LOGE("ERR(%s):Fail on SecCamera getPhyAddr Y addr = %0x C addr = %0x", __func__, phyYAddr, phyCAddr);
+ LOGE("ERR(%s):Fail on SecCamera getPhyAddr Y addr = %0x C addr = %0x",
+ __func__, phyYAddr, phyCAddr);
return UNKNOWN_ERROR;
}
@@ -482,37 +541,95 @@ int CameraHardwareSec::previewThread()
mSecCamera->getPreviewSize(&width, &height, &frame_size);
- offset = (frame_size + 16) * index;
- sp<MemoryBase> buffer = new MemoryBase(mPreviewHeap, offset, frame_size);
+ offset = (frame_size + mFrameSizeDelta) * index;
- memcpy(static_cast<unsigned char *>(mPreviewHeap->base()) + (offset + frame_size ), &phyYAddr, 4);
- memcpy(static_cast<unsigned char *>(mPreviewHeap->base()) + (offset + frame_size + 4), &phyCAddr, 4);
-
-#if defined(BOARD_USES_OVERLAY)
- if (mUseOverlay) {
- int ret;
- overlay_buffer_t overlay_buffer;
+#if 0 // FIXME: this does not seem to be necessary. Is it?
+ memcpy((char *)mPreviewHeap->data + offset + frame_size,
+ &phyYAddr, 4);
+ memcpy((char *)mPreviewHeap->data + offset + frame_size + 4,
+ &phyCAddr, 4);
+#endif
- mOverlayBufferIdx ^= 1;
- memcpy(static_cast<unsigned char*>(mPreviewHeap->base()) + offset + frame_size + sizeof(phyYAddr) + sizeof(phyCAddr),
- &mOverlayBufferIdx, sizeof(mOverlayBufferIdx));
+ if (mPreviewWindow && mGrallocHal) {
+ buffer_handle_t *buf_handle;
+ int stride;
+ if (0 != mPreviewWindow->dequeue_buffer(mPreviewWindow, &buf_handle, &stride)) {
+ LOGE("Could not dequeue gralloc buffer!\n");
+ goto callbacks;
+ }
- ret = mOverlay->queueBuffer((void*)(static_cast<unsigned char *>(mPreviewHeap->base()) + (offset + frame_size)));
+ void *vaddr;
+ if (!mGrallocHal->lock(mGrallocHal,
+ *buf_handle,
+ GRALLOC_USAGE_SW_WRITE_OFTEN,
+ 0, 0, width, height, &vaddr)) {
+ char *frame = ((char *)mPreviewHeap->data) + offset;
+ int total = frame_size + mFrameSizeDelta;
+
+ // the code below assumes YUV, not RGB
+ {
+ int h;
+ char *src = frame;
+ char *ptr = (char *)vaddr;
+
+ // Copy the Y plane, while observing the stride
+ for (h = 0; h < height; h++) {
+ memcpy(ptr, src, width);
+ ptr += stride;
+ src += width;
+ }
- if (ret == -1 ) {
- LOGE("ERR(%s):overlay queueBuffer fail", __func__);
- } else if (ret != ALL_BUFFERS_FLUSHED) {
- ret = mOverlay->dequeueBuffer(&overlay_buffer);
- if (ret == -1) {
- LOGE("ERR(%s):overlay dequeueBuffer fail", __func__);
+ {
+ // U
+ char *v = ptr;
+ ptr += stride * height / 4;
+ for (h = 0; h < height / 2; h++) {
+ memcpy(ptr, src, width / 2);
+ ptr += stride / 2;
+ src += width / 2;
+ }
+ // V
+ ptr = v;
+ for (h = 0; h < height / 2; h++) {
+ memcpy(ptr, src, width / 2);
+ ptr += stride / 2;
+ src += width / 2;
+ }
+ }
}
- }
- }
-#endif
+ mGrallocHal->unlock(mGrallocHal, *buf_handle);
+ }
+ else
+ LOGE("%s: could not obtain gralloc buffer", __func__);
+
+ if (0 != mPreviewWindow->enqueue_buffer(mPreviewWindow, buf_handle)) {
+ LOGE("Could not enqueue gralloc buffer!\n");
+ goto callbacks;
+ }
+ }
+
+callbacks:
// Notify the client of a new frame.
if (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
- mDataCb(CAMERA_MSG_PREVIEW_FRAME, buffer, mCallbackCookie);
+ const char * preview_format = mParameters.getPreviewFormat();
+ if (!strcmp(preview_format, CameraParameters::PIXEL_FORMAT_YUV420SP)) {
+ // Color conversion from YUV420 to NV21
+ char *vu = ((char *)mPreviewHeap->data) + offset + width * height;
+ const int uv_size = (width * height) >> 1;
+ char saved_uv[uv_size];
+ memcpy(saved_uv, vu, uv_size);
+ char *u = saved_uv;
+ char *v = u + (uv_size >> 1);
+
+ int h = 0;
+ while (h < width * height / 4) {
+ *vu++ = *v++;
+ *vu++ = *u++;
+ ++h;
+ }
+ }
+ mDataCb(CAMERA_MSG_PREVIEW_FRAME, mPreviewHeap, index, NULL, mCallbackCookie);
}
Mutex::Autolock lock(mRecordLock);
@@ -527,20 +644,22 @@ int CameraHardwareSec::previewThread()
phyCAddr = mSecCamera->getRecPhyAddrC(index);
if (phyYAddr == 0xffffffff || phyCAddr == 0xffffffff) {
- LOGE("ERR(%s):Fail on SecCamera getRectPhyAddr Y addr = %0x C addr = %0x", __func__, phyYAddr, phyCAddr);
+ LOGE("ERR(%s):Fail on SecCamera getRectPhyAddr Y addr = %0x C addr = %0x", __func__,
+ phyYAddr, phyCAddr);
return UNKNOWN_ERROR;
}
- addrs = (struct addrs *)mRecordHeap->base();
+ addrs = (struct addrs *)mRecordHeap->data;
- sp<MemoryBase> buffer = new MemoryBase(mRecordHeap, index * sizeof(struct addrs), sizeof(struct addrs));
+ addrs[index].type = kMetadataBufferTypeCameraSource;
addrs[index].addr_y = phyYAddr;
addrs[index].addr_cbcr = phyCAddr;
addrs[index].buf_index = index;
// Notify the client of a new frame.
if (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME) {
- mDataCbTimestamp(timestamp, CAMERA_MSG_VIDEO_FRAME, buffer, mCallbackCookie);
+ mDataCbTimestamp(timestamp, CAMERA_MSG_VIDEO_FRAME,
+ mRecordHeap, index, mCallbackCookie);
} else {
mSecCamera->releaseRecordFrame(index);
}
@@ -555,10 +674,8 @@ status_t CameraHardwareSec::startPreview()
LOGV("%s :", __func__);
- Mutex::Autolock lock(mStateLock);
- if (mCaptureInProgress) {
- LOGE("%s : capture in progress, not allowed", __func__);
- return INVALID_OPERATION;
+ if (waitCaptureCompletion() != NO_ERROR) {
+ return TIMED_OUT;
}
mPreviewLock.lock();
@@ -569,96 +686,78 @@ status_t CameraHardwareSec::startPreview()
return INVALID_OPERATION;
}
- setSkipFrame(INITIAL_SKIP_FRAME);
-
- ret = mSecCamera->startPreview();
- LOGV("%s : mSecCamera->startPreview() returned %d", __func__, ret);
+ mPreviewRunning = true;
+ mPreviewStartDeferred = false;
- if (ret < 0) {
- LOGE("ERR(%s):Fail on mSecCamera->startPreview()", __func__);
- return -1; //UNKNOWN_ERROR;
+ if (!mPreviewWindow) {
+ LOGI("%s : deferring", __func__);
+ mPreviewStartDeferred = true;
+ mPreviewLock.unlock();
+ return NO_ERROR;
}
- if (mPreviewHeap != NULL)
- mPreviewHeap.clear();
-
- int width, height, frame_size;
-
- mSecCamera->getPreviewSize(&width, &height, &frame_size);
-
- int previewHeapSize = (frame_size + 16) * kBufferCount;
-
- LOGD("MemoryHeapBase(fd(%d), size(%d), width(%d), height(%d))", (int)mSecCamera->getCameraFd(), (size_t)(previewHeapSize), width, height);
- mPreviewHeap = new MemoryHeapBase((int)mSecCamera->getCameraFd(), (size_t)(previewHeapSize), (uint32_t)0);
-
- mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize);
- LOGV("CameraHardwareSec: mPostViewWidth = %d mPostViewHeight = %d mPostViewSize = %d",mPostViewWidth,mPostViewHeight,mPostViewSize);
+ ret = startPreviewInternal();
+ if (ret == OK)
+ mPreviewCondition.signal();
- mPreviewRunning = true;
- mPreviewCondition.signal();
mPreviewLock.unlock();
-
- return NO_ERROR;
-}
-
-#if defined(BOARD_USES_OVERLAY)
-bool CameraHardwareSec::useOverlay()
-{
- LOGV("%s: returning true", __func__);
- return true;
+ return ret;
}
-status_t CameraHardwareSec::setOverlay(const sp<Overlay> &overlay)
+status_t CameraHardwareSec::startPreviewInternal()
{
- LOGV("%s :", __func__);
+ LOGV("%s", __func__);
- int overlayWidth = 0;
- int overlayHeight = 0;
- int overlayFrameSize = 0;
+ int ret = mSecCamera->startPreview();
+ LOGV("%s : mSecCamera->startPreview() returned %d", __func__, ret);
- if (overlay == NULL) {
- LOGV("%s : overlay == NULL", __func__);
- goto setOverlayFail;
+ if (ret < 0) {
+ LOGE("ERR(%s):Fail on mSecCamera->startPreview()", __func__);
+ return UNKNOWN_ERROR;
}
- LOGV("%s : overlay = %p", __func__, overlay->getHandleRef());
- if (overlay->getHandleRef()== NULL && mUseOverlay == true) {
- if (mOverlay != 0)
- mOverlay->destroy();
+ setSkipFrame(INITIAL_SKIP_FRAME);
- mOverlay = NULL;
- mUseOverlay = false;
+ int width, height, frame_size;
- return NO_ERROR;
- }
+ mSecCamera->getPreviewSize(&width, &height, &frame_size);
- if (overlay->getStatus() != NO_ERROR) {
- LOGE("ERR(%s):overlay->getStatus() fail", __func__);
- goto setOverlayFail;
+ LOGD("mPreviewHeap(fd(%d), size(%d), width(%d), height(%d))",
+ mSecCamera->getCameraFd(), frame_size + mFrameSizeDelta, width, height);
+ if (mPreviewHeap) {
+ mPreviewHeap->release(mPreviewHeap);
+ mPreviewHeap = 0;
}
- mSecCamera->getPreviewSize(&overlayWidth, &overlayHeight, &overlayFrameSize);
+ mPreviewHeap = mGetMemoryCb((int)mSecCamera->getCameraFd(),
+ frame_size + mFrameSizeDelta,
+ kBufferCount,
+ 0); // no cookie
- if (overlay->setCrop(0, 0, overlayWidth, overlayHeight) != NO_ERROR) {
- LOGE("ERR(%s)::(mOverlay->setCrop(0, 0, %d, %d) fail", __func__, overlayWidth, overlayHeight);
- goto setOverlayFail;
- }
-
- mOverlay = overlay;
- mUseOverlay = true;
+ mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize);
+ LOGV("CameraHardwareSec: mPostViewWidth = %d mPostViewHeight = %d mPostViewSize = %d",
+ mPostViewWidth,mPostViewHeight,mPostViewSize);
return NO_ERROR;
+}
-setOverlayFail :
- if (mOverlay != 0)
- mOverlay->destroy();
- mOverlay = 0;
-
- mUseOverlay = false;
+void CameraHardwareSec::stopPreviewInternal()
+{
+ LOGV("%s :", __func__);
- return UNKNOWN_ERROR;
+ /* request that the preview thread stop. */
+ if (mPreviewRunning) {
+ mPreviewRunning = false;
+ if (!mPreviewStartDeferred) {
+ mPreviewCondition.signal();
+ /* wait until preview thread is stopped */
+ mPreviewStoppedCondition.wait(mPreviewLock);
+ }
+ else
+ LOGV("%s : preview running but deferred, doing nothing", __func__);
+ } else
+ LOGI("%s : preview not running, doing nothing", __func__);
}
-#endif
void CameraHardwareSec::stopPreview()
{
@@ -666,14 +765,7 @@ void CameraHardwareSec::stopPreview()
/* request that the preview thread stop. */
mPreviewLock.lock();
- if (mPreviewRunning) {
- mPreviewRunning = false;
- mPreviewCondition.signal();
- /* wait until preview thread is stopped */
- mPreviewStoppedCondition.wait(mPreviewLock);
- } else {
- LOGI("%s : preview not running, doing nothing", __func__);
- }
+ stopPreviewInternal();
mPreviewLock.unlock();
}
@@ -692,6 +784,16 @@ status_t CameraHardwareSec::startRecording()
Mutex::Autolock lock(mRecordLock);
+ if (mRecordHeap) {
+ mRecordHeap->release(mRecordHeap);
+ mRecordHeap = 0;
+ }
+ mRecordHeap = mGetMemoryCb(-1, sizeof(struct addrs), kBufferCount, NULL);
+ if (!mRecordHeap) {
+ LOGE("ERR(%s): Record heap creation fail", __func__);
+ return UNKNOWN_ERROR;
+ }
+
if (mRecordRunning == false) {
if (mSecCamera->startRecord() < 0) {
LOGE("ERR(%s):Fail on mSecCamera->startRecord()", __func__);
@@ -724,12 +826,9 @@ bool CameraHardwareSec::recordingEnabled()
return mRecordRunning;
}
-void CameraHardwareSec::releaseRecordingFrame(const sp<IMemory>& mem)
+void CameraHardwareSec::releaseRecordingFrame(const void *opaque)
{
- ssize_t offset;
- sp<IMemoryHeap> heap = mem->getMemory(&offset, NULL);
- struct addrs *addrs = (struct addrs *)((uint8_t *)heap->base() + offset);
-
+ struct addrs *addrs = (struct addrs *)opaque;
mSecCamera->releaseRecordFrame(addrs->buf_index);
}
@@ -959,6 +1058,8 @@ int CameraHardwareSec::pictureThread()
int mPostViewWidth, mPostViewHeight, mPostViewSize;
int mThumbWidth, mThumbHeight, mThumbSize;
int cap_width, cap_height, cap_frame_size;
+ int JpegImageSize, JpegExifSize;
+ bool isLSISensor = false;
unsigned int output_size = 0;
@@ -974,58 +1075,52 @@ int CameraHardwareSec::pictureThread()
LOG_TIME_DEFINE(0)
LOG_TIME_START(0)
- sp<MemoryBase> buffer = new MemoryBase(mRawHeap, 0, mPostViewSize + 8);
+// sp<MemoryBase> buffer = new MemoryBase(mRawHeap, 0, mPostViewSize + 8);
- struct addrs_cap *addrs = (struct addrs_cap *)mRawHeap->base();
+ struct addrs_cap *addrs = (struct addrs_cap *)mRawHeap->data;
addrs[0].width = mPostViewWidth;
addrs[0].height = mPostViewHeight;
LOGV("[5B] mPostViewWidth = %d mPostViewHeight = %d\n",mPostViewWidth,mPostViewHeight);
- sp<MemoryHeapBase> JpegHeap = new MemoryHeapBase(mJpegHeapSize);
+ camera_memory_t *JpegHeap = mGetMemoryCb(-1, mJpegHeapSize, 1, 0);
sp<MemoryHeapBase> PostviewHeap = new MemoryHeapBase(mPostViewSize);
sp<MemoryHeapBase> ThumbnailHeap = new MemoryHeapBase(mThumbSize);
- if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE) {
- LOG_TIME_DEFINE(1)
- LOG_TIME_START(1)
+ LOG_TIME_DEFINE(1)
+ LOG_TIME_START(1)
- int picture_size, picture_width, picture_height;
- mSecCamera->getSnapshotSize(&picture_width, &picture_height, &picture_size);
- int picture_format = mSecCamera->getSnapshotPixelFormat();
+ int picture_size, picture_width, picture_height;
+ mSecCamera->getSnapshotSize(&picture_width, &picture_height, &picture_size);
+ int picture_format = mSecCamera->getSnapshotPixelFormat();
- unsigned int phyAddr;
+ unsigned int phyAddr;
- // Modified the shutter sound timing for Jpeg capture
- if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK)
- mSecCamera->setSnapshotCmd();
- if (mMsgEnabled & CAMERA_MSG_SHUTTER) {
- mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie);
- }
+ // Modified the shutter sound timing for Jpeg capture
+ if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK)
+ mSecCamera->setSnapshotCmd();
+ if (mMsgEnabled & CAMERA_MSG_SHUTTER) {
+ mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie);
+ }
- if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK){
- jpeg_data = mSecCamera->getJpeg(&jpeg_size, &phyAddr);
- if (jpeg_data == NULL) {
- LOGE("ERR(%s):Fail on SecCamera->getSnapshot()", __func__);
- ret = UNKNOWN_ERROR;
- }
- } else {
- if (mSecCamera->getSnapshotAndJpeg((unsigned char*)PostviewHeap->base(),
- (unsigned char*)JpegHeap->base(), &output_size) < 0) {
- mStateLock.lock();
- mCaptureInProgress = false;
- mStateLock.unlock();
- return UNKNOWN_ERROR;
- }
- LOGI("snapshotandjpeg done\n");
+ if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK){
+ jpeg_data = mSecCamera->getJpeg(&jpeg_size, &phyAddr);
+ if (jpeg_data == NULL) {
+ LOGE("ERR(%s):Fail on SecCamera->getSnapshot()", __func__);
+ ret = UNKNOWN_ERROR;
+ goto out;
}
-
- LOG_TIME_END(1)
- LOG_CAMERA("getSnapshotAndJpeg interval: %lu us", LOG_TIME(1));
+ } else {
+ if (mSecCamera->getSnapshotAndJpeg((unsigned char*)PostviewHeap->base(),
+ (unsigned char*)JpegHeap->data, &output_size) < 0) {
+ ret = UNKNOWN_ERROR;
+ goto out;
+ }
+ LOGI("snapshotandjpeg done\n");
}
- int JpegImageSize, JpegExifSize;
- bool isLSISensor = false;
+ LOG_TIME_END(1)
+ LOG_CAMERA("getSnapshotAndJpeg interval: %lu us", LOG_TIME(1));
if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK) {
isLSISensor = !strncmp((const char*)mCameraSensorName, "S5K4ECGX", 8);
@@ -1033,16 +1128,19 @@ int CameraHardwareSec::pictureThread()
LOGI("== Camera Sensor Detect %s - Samsung LSI SOC 5M ==\n", mCameraSensorName);
// LSI 5M SOC
if (!SplitFrame(jpeg_data, SecCamera::getInterleaveDataSize(),
- SecCamera::getJpegLineLength(),
- mPostViewWidth * 2, mPostViewWidth,
- JpegHeap->base(), &JpegImageSize,
- PostviewHeap->base(), &mPostViewSize))
- return UNKNOWN_ERROR;
+ SecCamera::getJpegLineLength(),
+ mPostViewWidth * 2, mPostViewWidth,
+ JpegHeap->data, &JpegImageSize,
+ PostviewHeap->base(), &mPostViewSize)) {
+ ret = UNKNOWN_ERROR;
+ goto out;
+ }
} else {
LOGI("== Camera Sensor Detect %s Sony SOC 5M ==\n", mCameraSensorName);
- decodeInterleaveData(jpeg_data, SecCamera::getInterleaveDataSize(), mPostViewWidth, mPostViewHeight,
- &JpegImageSize, JpegHeap->base(), PostviewHeap->base());
-
+ decodeInterleaveData(jpeg_data,
+ SecCamera::getInterleaveDataSize(),
+ mPostViewWidth, mPostViewHeight,
+ &JpegImageSize, JpegHeap->data, PostviewHeap->base());
}
} else {
JpegImageSize = static_cast<int>(output_size);
@@ -1050,70 +1148,36 @@ int CameraHardwareSec::pictureThread()
scaleDownYuv422((char *)PostviewHeap->base(), mPostViewWidth, mPostViewHeight,
(char *)ThumbnailHeap->base(), mThumbWidth, mThumbHeight);
- memcpy(mRawHeap->base(),PostviewHeap->base(), postviewHeapSize);
-
-#if defined(BOARD_USES_OVERLAY)
- /* Put postview image to Overlay */
- unsigned int index = 0;
- unsigned int offset = ((mPostViewWidth*mPostViewHeight*3/2) + 16) * index;
- unsigned int overlay_header[4];
-
- // Only show postview image if size is VGA since sensor cannot deliver
- // any other sizes.
- int previewWidth, previewHeight, previewSize;
- mSecCamera->getPreviewSize(&previewWidth, &previewHeight, &previewSize);
- if ((previewWidth != 640) || (previewHeight != 480))
- goto PostviewOverlayEnd;
-
- mOverlayBufferIdx ^= 1;
- overlay_header[0]= mSecCamera->getPhyAddrY(index);
- overlay_header[1]= overlay_header[0] + mPostViewWidth*mPostViewHeight;
- overlay_header[2]= mOverlayBufferIdx;
-
- YUY2toNV21(mRawHeap->base(), (void*)(static_cast<unsigned char *>(mPreviewHeap->base()) + offset),
- mPostViewWidth, mPostViewHeight);
-
- memcpy(static_cast<unsigned char*>(mPreviewHeap->base()) + offset + (mPostViewWidth*mPostViewHeight * 3 / 2),
- overlay_header, 16);
+ memcpy(mRawHeap->data, PostviewHeap->base(), postviewHeapSize);
- ret = mOverlay->queueBuffer((void*)(static_cast<unsigned char *>(mPreviewHeap->base()) + offset +
- (mPostViewWidth*mPostViewHeight * 3 / 2)));
-
- if (ret == -1) {
- LOGE("ERR(%s):overlay queueBuffer fail", __func__);
- } else if (ret != ALL_BUFFERS_FLUSHED) {
- overlay_buffer_t overlay_buffer;
- ret = mOverlay->dequeueBuffer(&overlay_buffer);
- if (ret == -1) {
- LOGE("ERR(%s):overlay dequeueBuffer fail", __func__);
- }
- }
-
-PostviewOverlayEnd:
-#endif
if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE) {
- mDataCb(CAMERA_MSG_RAW_IMAGE, buffer, mCallbackCookie);
+ mDataCb(CAMERA_MSG_RAW_IMAGE, mRawHeap, 0, NULL, mCallbackCookie);
+ } else if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE_NOTIFY) {
+ mNotifyCb(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, mCallbackCookie);
}
+
if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) {
- sp<MemoryHeapBase> ExifHeap = new MemoryHeapBase(EXIF_FILE_SIZE + JPG_STREAM_BUF_SIZE);
- JpegExifSize = mSecCamera->getExif((unsigned char *)ExifHeap->base(),
- (unsigned char *)ThumbnailHeap->base());
+ camera_memory_t *ExifHeap =
+ mGetMemoryCb(-1, EXIF_FILE_SIZE + JPG_STREAM_BUF_SIZE, 1, 0);
+ JpegExifSize = mSecCamera->getExif((unsigned char *)ExifHeap->data,
+ (unsigned char *)ThumbnailHeap->base());
LOGV("JpegExifSize=%d", JpegExifSize);
if (JpegExifSize < 0) {
ret = UNKNOWN_ERROR;
+ ExifHeap->release(ExifHeap);
goto out;
}
- unsigned char *ExifStart = (unsigned char *)JpegHeap->base() + 2;
- unsigned char *ImageStart = ExifStart + JpegExifSize;
-
- memmove(ImageStart, ExifStart, JpegImageSize - 2);
- memcpy(ExifStart, ExifHeap->base(), JpegExifSize);
- sp<MemoryBase> mem = new MemoryBase(JpegHeap, 0, JpegImageSize + JpegExifSize);
-
- mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, mCallbackCookie);
+ camera_memory_t *mem = mGetMemoryCb(-1, JpegImageSize + JpegExifSize, 1, 0);
+ uint8_t *ptr = (uint8_t *) mem->data;
+ memcpy(ptr, JpegHeap->data, 2); ptr += 2;
+ memcpy(ptr, ExifHeap->data, JpegExifSize); ptr += JpegExifSize;
+ memcpy(ptr, (uint8_t *) JpegHeap->data + 2, JpegImageSize - 2);
+ mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, 0, NULL, mCallbackCookie);
+ mem->release(mem);
+ ExifHeap->release(ExifHeap);
}
LOG_TIME_END(0)
@@ -1122,37 +1186,71 @@ PostviewOverlayEnd:
LOGV("%s : pictureThread end", __func__);
out:
- mStateLock.lock();
+ JpegHeap->release(JpegHeap);
+ mSecCamera->endSnapshot();
+ mCaptureLock.lock();
mCaptureInProgress = false;
- mStateLock.unlock();
+ mCaptureCondition.broadcast();
+ mCaptureLock.unlock();
return ret;
}
+status_t CameraHardwareSec::waitCaptureCompletion() {
+ // 5 seconds timeout
+ nsecs_t endTime = 5000000000LL + systemTime(SYSTEM_TIME_MONOTONIC);
+ Mutex::Autolock lock(mCaptureLock);
+ while (mCaptureInProgress) {
+ nsecs_t remainingTime = endTime - systemTime(SYSTEM_TIME_MONOTONIC);
+ if (remainingTime <= 0) {
+ LOGE("Timed out waiting picture thread.");
+ return TIMED_OUT;
+ }
+ LOGD("Waiting for picture thread to complete.");
+ mCaptureCondition.waitRelative(mCaptureLock, remainingTime);
+ }
+ return NO_ERROR;
+}
+
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 (!mRawHeap) {
+ int rawHeapSize = mPostViewSize;
+ LOGV("mRawHeap : MemoryHeapBase(previewHeapSize(%d))", rawHeapSize);
+ mRawHeap = mGetMemoryCb(-1, rawHeapSize, 1, 0);
+ if (!mRawHeap) {
+ LOGE("ERR(%s): Raw heap creation fail", __func__);
+ }
+ }
+
+ if (waitCaptureCompletion() != NO_ERROR) {
+ return TIMED_OUT;
}
if (mPictureThread->run("CameraPictureThread", PRIORITY_DEFAULT) != NO_ERROR) {
LOGE("%s : couldn't run picture thread", __func__);
return INVALID_OPERATION;
}
+ mCaptureLock.lock();
mCaptureInProgress = true;
+ mCaptureLock.unlock();
return NO_ERROR;
}
status_t CameraHardwareSec::cancelPicture()
{
- mPictureThread->requestExitAndWait();
+ LOGV("%s", __func__);
+
+ if (mPictureThread.get()) {
+ LOGV("%s: waiting for picture thread to exit", __func__);
+ mPictureThread->requestExitAndWait();
+ LOGV("%s: picture thread has exited", __func__);
+ }
return NO_ERROR;
}
@@ -1212,7 +1310,7 @@ bool CameraHardwareSec::SplitFrame(unsigned char *pFrame, int dwSize,
LOGV("===========SplitFrame Start==============");
if (NULL == pFrame || 0 >= dwSize) {
- LOGE("There is no contents.\r\n");
+ LOGE("There is no contents (pFrame=%p, dwSize=%d", pFrame, dwSize);
return false;
}
@@ -1387,14 +1485,15 @@ int CameraHardwareSec::decodeInterleaveData(unsigned char *pInterleaveData,
return ret;
}
-status_t CameraHardwareSec::dump(int fd, const Vector<String16>& args) const
+status_t CameraHardwareSec::dump(int fd) const
{
const size_t SIZE = 256;
char buffer[SIZE];
String8 result;
+ const Vector<String16> args;
if (mSecCamera != 0) {
- mSecCamera->dump(fd, args);
+ mSecCamera->dump(fd);
mParameters.dump(fd, args);
mInternalParameters.dump(fd, args);
snprintf(buffer, 255, " preview running(%s)\n", mPreviewRunning?"true": "false");
@@ -1420,6 +1519,33 @@ bool CameraHardwareSec::isSupportedPreviewSize(const int width,
return false;
}
+bool CameraHardwareSec::isSupportedParameter(const char * const parm,
+ const char * const supported_parm) const
+{
+ const char *pStart;
+ const char *pEnd;
+
+ if (!parm || !supported_parm)
+ return false;
+
+ pStart = supported_parm;
+
+ while (true) {
+ pEnd = strchr(pStart, ',');
+ if (!pEnd) {
+ if (!strcmp(parm, pStart))
+ return true;
+ else
+ return false;
+ }
+ if (!strncmp(parm, pStart, pEnd - pStart)) {
+ return true;
+ }
+ pStart = pEnd + 1;
+ }
+ /* NOTREACHED */
+}
+
status_t CameraHardwareSec::setParameters(const CameraParameters& params)
{
LOGV("%s :", __func__);
@@ -1427,16 +1553,11 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params)
status_t ret = NO_ERROR;
/* if someone calls us while picture thread is running, it could screw
- * up the sensor quite a bit so return error. we can't wait because
- * that would cause deadlock with the callbacks
+ * up the sensor quite a bit so return error.
*/
- mStateLock.lock();
- if (mCaptureInProgress) {
- mStateLock.unlock();
- LOGE("%s : capture in progress, not allowed", __func__);
- return UNKNOWN_ERROR;
+ if (waitCaptureCompletion() != NO_ERROR) {
+ return TIMED_OUT;
}
- mStateLock.unlock();
// preview size
int new_preview_width = 0;
@@ -1446,44 +1567,54 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params)
LOGV("%s : new_preview_width x new_preview_height = %dx%d, format = %s",
__func__, new_preview_width, new_preview_height, new_str_preview_format);
+ if (strcmp(new_str_preview_format, CameraParameters::PIXEL_FORMAT_YUV420SP) &&
+ strcmp(new_str_preview_format, CameraParameters::PIXEL_FORMAT_YUV420P)) {
+ LOGE("Unsupported preview color format: %s", new_str_preview_format);
+ return BAD_VALUE;
+ }
+
if (0 < new_preview_width && 0 < new_preview_height &&
new_str_preview_format != NULL &&
isSupportedPreviewSize(new_preview_width, new_preview_height)) {
- int new_preview_format = 0;
-
- if (!strcmp(new_str_preview_format,
- CameraParameters::PIXEL_FORMAT_RGB565))
- new_preview_format = V4L2_PIX_FMT_RGB565;
- else if (!strcmp(new_str_preview_format,
- CameraParameters::PIXEL_FORMAT_YUV420SP))
- new_preview_format = V4L2_PIX_FMT_NV21;
- else if (!strcmp(new_str_preview_format, "yuv420sp_custom"))
- new_preview_format = V4L2_PIX_FMT_NV12T;
- else if (!strcmp(new_str_preview_format, "yuv420p"))
- new_preview_format = V4L2_PIX_FMT_YUV420;
- else if (!strcmp(new_str_preview_format, "yuv422i"))
- new_preview_format = V4L2_PIX_FMT_YUYV;
- else if (!strcmp(new_str_preview_format, "yuv422p"))
- new_preview_format = V4L2_PIX_FMT_YUV422P;
- else
- new_preview_format = V4L2_PIX_FMT_NV21; //for 3rd party
+ int new_preview_format = V4L2_PIX_FMT_YUV420;
+ mFrameSizeDelta = 16;
+
+ int current_preview_width, current_preview_height, current_frame_size;
+ mSecCamera->getPreviewSize(&current_preview_width,
+ &current_preview_height,
+ &current_frame_size);
+ int current_pixel_format = mSecCamera->getPreviewPixelFormat();
+
+ if (current_preview_width != new_preview_width ||
+ current_preview_height != new_preview_height ||
+ current_pixel_format != new_preview_format) {
+ if (mSecCamera->setPreviewSize(new_preview_width, new_preview_height,
+ new_preview_format) < 0) {
+ LOGE("ERR(%s):Fail on mSecCamera->setPreviewSize(width(%d), height(%d), format(%d))",
+ __func__, new_preview_width, new_preview_height, new_preview_format);
+ ret = UNKNOWN_ERROR;
+ } else {
+ if (mPreviewWindow) {
+ if (mPreviewRunning && !mPreviewStartDeferred) {
+ LOGE("ERR(%s): preview is running, cannot change size and format!",
+ __func__);
+ ret = INVALID_OPERATION;
+ }
+
+ LOGV("%s: mPreviewWindow (%p) set_buffers_geometry", __func__, mPreviewWindow);
+ LOGV("%s: mPreviewWindow->set_buffers_geometry (%p)", __func__,
+ mPreviewWindow->set_buffers_geometry);
+ mPreviewWindow->set_buffers_geometry(mPreviewWindow,
+ new_preview_width, new_preview_height,
+ new_preview_format);
+ LOGV("%s: DONE mPreviewWindow (%p) set_buffers_geometry", __func__, mPreviewWindow);
+ }
- if (mSecCamera->setPreviewSize(new_preview_width, new_preview_height, new_preview_format) < 0) {
- LOGE("ERR(%s):Fail on mSecCamera->setPreviewSize(width(%d), height(%d), format(%d))",
- __func__, new_preview_width, new_preview_height, new_preview_format);
- ret = UNKNOWN_ERROR;
- } else {
mParameters.setPreviewSize(new_preview_width, new_preview_height);
mParameters.setPreviewFormat(new_str_preview_format);
- }
-#if defined(BOARD_USES_OVERLAY)
- if (mUseOverlay == true && mOverlay != 0) {
- if (mOverlay->setCrop(0, 0, new_preview_width, new_preview_height) != NO_ERROR) {
- LOGE("ERR(%s)::(mOverlay->setCrop(0, 0, %d, %d) fail",
- __func__, new_preview_width, new_preview_height);
}
}
-#endif
+ else LOGV("%s: preview size and format has not changed", __func__);
} else {
LOGE("%s: Invalid preview size(%dx%d)",
__func__, new_preview_width, new_preview_height);
@@ -1497,6 +1628,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params)
params.getPictureSize(&new_picture_width, &new_picture_height);
LOGV("%s : new_picture_width x new_picture_height = %dx%d", __func__, new_picture_width, new_picture_height);
if (0 < new_picture_width && 0 < new_picture_height) {
+ LOGV("%s: setSnapshotSize", __func__);
if (mSecCamera->setSnapshotSize(new_picture_width, new_picture_height) < 0) {
LOGE("ERR(%s):Fail on mSecCamera->setSnapshotSize(width(%d), height(%d))",
__func__, new_picture_width, new_picture_height);
@@ -1514,6 +1646,8 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params)
if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_RGB565))
new_picture_format = V4L2_PIX_FMT_RGB565;
+ else if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_RGBA8888))
+ new_picture_format = V4L2_PIX_FMT_RGB32;
else if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_YUV420SP))
new_picture_format = V4L2_PIX_FMT_NV21;
else if (!strcmp(new_str_picture_format, "yuv420sp_custom"))
@@ -1671,13 +1805,13 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params)
ret = UNKNOWN_ERROR;
}
- if (new_scene_mode_str != NULL) {
+ const char *new_focus_mode_str = params.get(CameraParameters::KEY_FOCUS_MODE);
+
+ if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK) {
int new_scene_mode = -1;
const char *new_flash_mode_str = params.get(CameraParameters::KEY_FLASH_MODE);
- const char *new_focus_mode_str;
- new_focus_mode_str = params.get(CameraParameters::KEY_FOCUS_MODE);
// fps range is (15000,30000) by default.
mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(15000,30000)");
mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
@@ -1685,6 +1819,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params)
if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_AUTO)) {
new_scene_mode = SCENE_MODE_NONE;
+ mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES, "on,off,auto,torch");
} else {
// defaults for non-auto scene modes
if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK) {
@@ -1696,36 +1831,52 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params)
CameraParameters::SCENE_MODE_PORTRAIT)) {
new_scene_mode = SCENE_MODE_PORTRAIT;
new_flash_mode_str = CameraParameters::FLASH_MODE_AUTO;
+ mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES, "auto");
} else if (!strcmp(new_scene_mode_str,
CameraParameters::SCENE_MODE_LANDSCAPE)) {
new_scene_mode = SCENE_MODE_LANDSCAPE;
+ new_flash_mode_str = CameraParameters::FLASH_MODE_OFF;
+ mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES, "off");
} else if (!strcmp(new_scene_mode_str,
CameraParameters::SCENE_MODE_SPORTS)) {
new_scene_mode = SCENE_MODE_SPORTS;
+ new_flash_mode_str = CameraParameters::FLASH_MODE_OFF;
+ mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES, "off");
} else if (!strcmp(new_scene_mode_str,
CameraParameters::SCENE_MODE_PARTY)) {
new_scene_mode = SCENE_MODE_PARTY_INDOOR;
new_flash_mode_str = CameraParameters::FLASH_MODE_AUTO;
+ mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES, "auto");
} else if ((!strcmp(new_scene_mode_str,
CameraParameters::SCENE_MODE_BEACH)) ||
(!strcmp(new_scene_mode_str,
CameraParameters::SCENE_MODE_SNOW))) {
new_scene_mode = SCENE_MODE_BEACH_SNOW;
+ new_flash_mode_str = CameraParameters::FLASH_MODE_OFF;
+ mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES, "off");
} else if (!strcmp(new_scene_mode_str,
CameraParameters::SCENE_MODE_SUNSET)) {
new_scene_mode = SCENE_MODE_SUNSET;
+ new_flash_mode_str = CameraParameters::FLASH_MODE_OFF;
+ mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES, "off");
} else if (!strcmp(new_scene_mode_str,
CameraParameters::SCENE_MODE_NIGHT)) {
new_scene_mode = SCENE_MODE_NIGHTSHOT;
mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(4000,30000)");
mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
"4000,30000");
+ new_flash_mode_str = CameraParameters::FLASH_MODE_OFF;
+ mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES, "off");
} else if (!strcmp(new_scene_mode_str,
CameraParameters::SCENE_MODE_FIREWORKS)) {
new_scene_mode = SCENE_MODE_FIREWORKS;
+ new_flash_mode_str = CameraParameters::FLASH_MODE_OFF;
+ mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES, "off");
} else if (!strcmp(new_scene_mode_str,
CameraParameters::SCENE_MODE_CANDLELIGHT)) {
new_scene_mode = SCENE_MODE_CANDLE_LIGHT;
+ new_flash_mode_str = CameraParameters::FLASH_MODE_OFF;
+ mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES, "off");
} else {
LOGE("%s::unmatched scene_mode(%s)",
__func__, new_scene_mode_str); //action, night-portrait, theatre, steadyphoto
@@ -1805,6 +1956,12 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params)
mParameters.set(CameraParameters::KEY_SCENE_MODE, new_scene_mode_str);
}
}
+ } else {
+ if (!isSupportedParameter(new_focus_mode_str,
+ mParameters.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES))) {
+ LOGE("%s: Unsupported focus mode: %s", __func__, new_focus_mode_str);
+ ret = UNKNOWN_ERROR;
+ }
}
// ---------------------------------------------------------------------------
@@ -2080,7 +2237,7 @@ status_t CameraHardwareSec::sendCommand(int32_t command, int32_t arg1, int32_t a
void CameraHardwareSec::release()
{
- LOGV("%s :", __func__);
+ LOGV("%s", __func__);
/* shut down any threads we have that might be running. do it here
* instead of the destructor. we're guaranteed to be on another thread
@@ -2116,51 +2273,36 @@ void CameraHardwareSec::release()
mPictureThread->requestExitAndWait();
mPictureThread.clear();
}
- if (mRawHeap != NULL)
- mRawHeap.clear();
- if (mJpegHeap != NULL)
- mJpegHeap.clear();
-
- if (mPreviewHeap != NULL) {
- LOGI("%s: calling mPreviewHeap.dispose()", __func__);
- mPreviewHeap->dispose();
- mPreviewHeap.clear();
+ if (mRawHeap) {
+ mRawHeap->release(mRawHeap);
+ mRawHeap = 0;
}
-
- if (mRecordHeap != NULL)
- mRecordHeap.clear();
-
-#if defined(BOARD_USES_OVERLAY)
- if (mUseOverlay) {
- mOverlay->destroy();
- mUseOverlay = false;
- mOverlay = NULL;
+ if (mPreviewHeap) {
+ mPreviewHeap->release(mPreviewHeap);
+ mPreviewHeap = 0;
+ }
+ if (mRecordHeap) {
+ mRecordHeap->release(mRecordHeap);
+ mRecordHeap = 0;
}
-#endif
- /* close after all the heaps are cleared since those
+ /* close after all the heaps are cleared since those
* could have dup'd our file descriptor.
*/
mSecCamera->DeinitCamera();
- mSecCamera = NULL;
-
}
-wp<CameraHardwareInterface> CameraHardwareSec::singleton;
-
-sp<CameraHardwareInterface> CameraHardwareSec::createInstance(int cameraId)
+status_t CameraHardwareSec::storeMetaDataInBuffers(bool enable)
{
- LOGV("%s :", __func__);
- if (singleton != 0) {
- sp<CameraHardwareInterface> hardware = singleton.promote();
- if (hardware != 0) {
- return hardware;
- }
+ // FIXME:
+ // metadata buffer mode can be turned on or off.
+ // Samsung needs to fix this.
+ if (!enable) {
+ LOGE("Non-metadata buffer mode is not supported!");
+ return INVALID_OPERATION;
}
- sp<CameraHardwareInterface> hardware(new CameraHardwareSec(cameraId));
- singleton = hardware;
- return hardware;
+ return OK;
}
static CameraInfo sCameraInfo[] = {
@@ -2174,19 +2316,408 @@ static CameraInfo sCameraInfo[] = {
}
};
-extern "C" int HAL_getNumberOfCameras()
+/** Close this device */
+
+static camera_device_t *g_cam_device;
+
+static int HAL_camera_device_close(struct hw_device_t* device)
+{
+ LOGI("%s", __func__);
+ if (device) {
+ camera_device_t *cam_device = (camera_device_t *)device;
+ delete static_cast<CameraHardwareSec *>(cam_device->priv);
+ free(cam_device);
+ g_cam_device = 0;
+ }
+ return 0;
+}
+
+static inline CameraHardwareSec *obj(struct camera_device *dev)
+{
+ return reinterpret_cast<CameraHardwareSec *>(dev->priv);
+}
+
+/** 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)
+{
+ LOGV("%s", __func__);
+ return obj(dev)->setPreviewWindow(buf);
+}
+
+/** 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)
+{
+ LOGV("%s", __func__);
+ obj(dev)->setCallbacks(notify_cb, data_cb, data_cb_timestamp,
+ get_memory,
+ user);
+}
+
+/**
+ * The following three functions all take a msg_type, which is a bitmask of
+ * the messages defined in include/ui/Camera.h
+ */
+
+/**
+ * Enable a message, or set of messages.
+ */
+static void HAL_camera_device_enable_msg_type(struct camera_device *dev, int32_t msg_type)
+{
+ LOGV("%s", __func__);
+ obj(dev)->enableMsgType(msg_type);
+}
+
+/**
+ * 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)
{
+ LOGV("%s", __func__);
+ obj(dev)->disableMsgType(msg_type);
+}
+
+/**
+ * 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)
+{
+ LOGV("%s", __func__);
+ return obj(dev)->msgTypeEnabled(msg_type);
+}
+
+/**
+ * Start preview mode.
+ */
+static int HAL_camera_device_start_preview(struct camera_device *dev)
+{
+ LOGV("%s", __func__);
+ return obj(dev)->startPreview();
+}
+
+/**
+ * Stop a previously started preview.
+ */
+static void HAL_camera_device_stop_preview(struct camera_device *dev)
+{
+ LOGV("%s", __func__);
+ obj(dev)->stopPreview();
+}
+
+/**
+ * Returns true if preview is enabled.
+ */
+static int HAL_camera_device_preview_enabled(struct camera_device *dev)
+{
+ LOGV("%s", __func__);
+ return obj(dev)->previewEnabled();
+}
+
+/**
+ * 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)
+{
+ LOGV("%s", __func__);
+ return obj(dev)->storeMetaDataInBuffers(enable);
+}
+
+/**
+ * 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)
+{
+ LOGV("%s", __func__);
+ return obj(dev)->startRecording();
+}
+
+/**
+ * Stop a previously started recording.
+ */
+static void HAL_camera_device_stop_recording(struct camera_device *dev)
+{
+ LOGV("%s", __func__);
+ obj(dev)->stopRecording();
+}
+
+/**
+ * Returns true if recording is enabled.
+ */
+static int HAL_camera_device_recording_enabled(struct camera_device *dev)
+{
+ LOGV("%s", __func__);
+ return obj(dev)->recordingEnabled();
+}
+
+/**
+ * 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)
+{
+ LOGV("%s", __func__);
+ obj(dev)->releaseRecordingFrame(opaque);
+}
+
+/**
+ * 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)
+{
+ LOGV("%s", __func__);
+ return obj(dev)->autoFocus();
+}
+
+/**
+ * Cancels auto-focus function. If the auto-focus is still in progress,
+ * this function will cancel it. Whether the auto-focus is in progress or
+ * not, this function will return the focus position to the default. If
+ * the camera does not support auto-focus, this is a no-op.
+ */
+static int HAL_camera_device_cancel_auto_focus(struct camera_device *dev)
+{
+ LOGV("%s", __func__);
+ return obj(dev)->cancelAutoFocus();
+}
+
+/**
+ * Take a picture.
+ */
+static int HAL_camera_device_take_picture(struct camera_device *dev)
+{
+ LOGV("%s", __func__);
+ return obj(dev)->takePicture();
+}
+
+/**
+ * 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)
+{
+ LOGV("%s", __func__);
+ return obj(dev)->cancelPicture();
+}
+
+/**
+ * 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)
+{
+ LOGV("%s", __func__);
+ String8 str(parms);
+ CameraParameters p(str);
+ return obj(dev)->setParameters(p);
+}
+
+/** Return the camera parameters. */
+char *HAL_camera_device_get_parameters(struct camera_device *dev)
+{
+ LOGV("%s", __func__);
+ String8 str;
+ CameraParameters parms = obj(dev)->getParameters();
+ str = parms.flatten();
+ return strdup(str.string());
+}
+
+void HAL_camera_device_put_parameters(struct camera_device *dev, char *parms)
+{
+ LOGV("%s", __func__);
+ free(parms);
+}
+
+/**
+ * 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)
+{
+ LOGV("%s", __func__);
+ return obj(dev)->sendCommand(cmd, arg1, arg2);
+}
+
+/**
+ * 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)
+{
+ LOGV("%s", __func__);
+ obj(dev)->release();
+}
+
+/**
+ * Dump state of the camera hardware
+ */
+static int HAL_camera_device_dump(struct camera_device *dev, int fd)
+{
+ LOGV("%s", __func__);
+ return obj(dev)->dump(fd);
+}
+
+static int HAL_getNumberOfCameras()
+{
+ LOGV("%s", __func__);
return sizeof(sCameraInfo) / sizeof(sCameraInfo[0]);
}
-extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo *cameraInfo)
+static int HAL_getCameraInfo(int cameraId, struct camera_info *cameraInfo)
{
+ LOGV("%s", __func__);
memcpy(cameraInfo, &sCameraInfo[cameraId], sizeof(CameraInfo));
+ return 0;
}
-extern "C" sp<CameraHardwareInterface> HAL_openCameraHardware(int cameraId)
+#define SET_METHOD(m) m : HAL_camera_device_##m
+
+static camera_device_ops_t camera_device_ops = {
+ SET_METHOD(set_preview_window),
+ SET_METHOD(set_callbacks),
+ SET_METHOD(enable_msg_type),
+ SET_METHOD(disable_msg_type),
+ SET_METHOD(msg_type_enabled),
+ SET_METHOD(start_preview),
+ SET_METHOD(stop_preview),
+ SET_METHOD(preview_enabled),
+ SET_METHOD(store_meta_data_in_buffers),
+ SET_METHOD(start_recording),
+ SET_METHOD(stop_recording),
+ SET_METHOD(recording_enabled),
+ SET_METHOD(release_recording_frame),
+ SET_METHOD(auto_focus),
+ SET_METHOD(cancel_auto_focus),
+ SET_METHOD(take_picture),
+ SET_METHOD(cancel_picture),
+ SET_METHOD(set_parameters),
+ SET_METHOD(get_parameters),
+ SET_METHOD(put_parameters),
+ SET_METHOD(send_command),
+ SET_METHOD(release),
+ SET_METHOD(dump),
+};
+
+#undef SET_METHOD
+
+static int HAL_camera_device_open(const struct hw_module_t* module,
+ const char *id,
+ struct hw_device_t** device)
{
- return CameraHardwareSec::createInstance(cameraId);
+ LOGV("%s", __func__);
+
+ int cameraId = atoi(id);
+ if (cameraId < 0 || cameraId >= HAL_getNumberOfCameras()) {
+ LOGE("Invalid camera ID %s", id);
+ return -EINVAL;
+ }
+
+ if (g_cam_device) {
+ if (obj(g_cam_device)->getCameraId() == cameraId) {
+ LOGV("returning existing camera ID %s", id);
+ goto done;
+ } else {
+ LOGE("Cannot open camera %d. camera %d is already running!",
+ cameraId, obj(g_cam_device)->getCameraId());
+ return -ENOSYS;
+ }
+ }
+
+ g_cam_device = (camera_device_t *)malloc(sizeof(camera_device_t));
+ if (!g_cam_device)
+ return -ENOMEM;
+
+ g_cam_device->common.tag = HARDWARE_DEVICE_TAG;
+ g_cam_device->common.version = 1;
+ g_cam_device->common.module = const_cast<hw_module_t *>(module);
+ g_cam_device->common.close = HAL_camera_device_close;
+
+ g_cam_device->ops = &camera_device_ops;
+
+ LOGI("%s: open camera %s", __func__, id);
+
+ g_cam_device->priv = new CameraHardwareSec(cameraId, g_cam_device);
+
+done:
+ *device = (hw_device_t *)g_cam_device;
+ LOGI("%s: opened camera %s (%p)", __func__, id, *device);
+ return 0;
+}
+
+static hw_module_methods_t camera_module_methods = {
+ open : HAL_camera_device_open
+};
+
+extern "C" {
+ struct camera_module HAL_MODULE_INFO_SYM = {
+ common : {
+ tag : HARDWARE_MODULE_TAG,
+ version_major : 1,
+ version_minor : 0,
+ id : CAMERA_HARDWARE_MODULE_ID,
+ name : "Crespo camera HAL",
+ author : "Samsung Corporation",
+ methods : &camera_module_methods,
+ },
+ get_number_of_cameras : HAL_getNumberOfCameras,
+ get_camera_info : HAL_getCameraInfo
+ };
}
}; // namespace android
diff --git a/libcamera/SecCameraHWInterface.h b/libcamera/SecCameraHWInterface.h
index 97c0a35..3254b7b 100644
--- a/libcamera/SecCameraHWInterface.h
+++ b/libcamera/SecCameraHWInterface.h
@@ -21,20 +21,20 @@
#include "SecCamera.h"
#include <utils/threads.h>
-#include <camera/CameraHardwareInterface.h>
+#include <utils/RefBase.h>
#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
-#include <utils/threads.h>
+#include <hardware/camera.h>
+#include <hardware/gralloc.h>
+#include <camera/CameraParameters.h>
namespace android {
-class CameraHardwareSec : public CameraHardwareInterface {
+ class CameraHardwareSec : public virtual RefBase {
public:
- virtual sp<IMemoryHeap> getPreviewHeap() const;
- virtual sp<IMemoryHeap> getRawHeap() const;
-
- virtual void setCallbacks(notify_callback notify_cb,
- data_callback data_cb,
- data_callback_timestamp data_cb_timestamp,
+ virtual void setCallbacks(camera_notify_callback notify_cb,
+ camera_data_callback data_cb,
+ camera_data_timestamp_callback data_cb_timestamp,
+ camera_request_memory get_memory,
void *user);
virtual void enableMsgType(int32_t msgType);
@@ -42,37 +42,33 @@ public:
virtual bool msgTypeEnabled(int32_t msgType);
virtual status_t startPreview();
-#if defined(BOARD_USES_OVERLAY)
- virtual bool useOverlay();
- virtual status_t setOverlay(const sp<Overlay> &overlay);
-#endif
virtual void stopPreview();
virtual bool previewEnabled();
virtual status_t startRecording();
virtual void stopRecording();
virtual bool recordingEnabled();
- virtual void releaseRecordingFrame(const sp<IMemory> &mem);
+ virtual void releaseRecordingFrame(const void *opaque);
virtual status_t autoFocus();
virtual status_t cancelAutoFocus();
virtual status_t takePicture();
virtual status_t cancelPicture();
- virtual status_t dump(int fd, const Vector<String16> &args) const;
+ virtual status_t dump(int fd) const;
virtual status_t setParameters(const CameraParameters& params);
virtual CameraParameters getParameters() const;
- virtual status_t sendCommand(int32_t command, int32_t arg1,
- int32_t arg2);
- virtual status_t setPreviewWindow(const sp<ANativeWindow>& buf);
+ virtual status_t sendCommand(int32_t command, int32_t arg1, int32_t arg2);
+ virtual status_t setPreviewWindow(preview_stream_ops *w);
+ virtual status_t storeMetaDataInBuffers(bool enable);
virtual void release();
- static sp<CameraHardwareInterface> createInstance(int cameraId);
+ inline int getCameraId() const;
-private:
- CameraHardwareSec(int cameraId);
+ CameraHardwareSec(int cameraId, camera_device_t *dev);
virtual ~CameraHardwareSec();
-
- static wp<CameraHardwareInterface> singleton;
+private:
+ status_t startPreviewInternal();
+ void stopPreviewInternal();
static const int kBufferCount = MAX_BUFFERS;
static const int kBufferCountForRecord = MAX_BUFFERS;
@@ -100,7 +96,6 @@ private:
mHardware(hw) { }
virtual bool threadLoop() {
mHardware->pictureThread();
- mHardware->mSecCamera->endSnapshot();
return false;
}
};
@@ -159,6 +154,9 @@ private:
void setSkipFrame(int frame);
bool isSupportedPreviewSize(const int width,
const int height) const;
+ bool isSupportedParameter(const char * const parm,
+ const char * const supported_parm) const;
+ status_t waitCaptureCompletion();
/* used by auto focus thread to block until it's told to run */
mutable Mutex mFocusLock;
mutable Condition mFocusCondition;
@@ -169,36 +167,33 @@ private:
mutable Condition mPreviewCondition;
mutable Condition mPreviewStoppedCondition;
bool mPreviewRunning;
+ bool mPreviewStartDeferred;
bool mExitPreviewThread;
- /* used to guard threading state */
- mutable Mutex mStateLock;
+ preview_stream_ops *mPreviewWindow;
+
+ /* used to guard mCaptureInProgress */
+ mutable Mutex mCaptureLock;
+ mutable Condition mCaptureCondition;
CameraParameters mParameters;
CameraParameters mInternalParameters;
- sp<MemoryHeapBase> mPreviewHeap;
- sp<MemoryHeapBase> mRawHeap;
- sp<MemoryHeapBase> mRecordHeap;
- sp<MemoryHeapBase> mJpegHeap;
- sp<MemoryBase> mBuffers[kBufferCount];
- sp<MemoryBase> mRecordBuffers[kBufferCountForRecord];
+ int mFrameSizeDelta;
+ camera_memory_t *mPreviewHeap;
+ camera_memory_t *mRawHeap;
+ camera_memory_t *mRecordHeap;
- SecCamera *mSecCamera;
+ SecCamera *mSecCamera;
const __u8 *mCameraSensorName;
mutable Mutex mSkipFrameLock;
int mSkipFrame;
-#if defined(BOARD_USES_OVERLAY)
- sp<Overlay> mOverlay;
- bool mUseOverlay;
- int mOverlayBufferIdx;
-#endif
-
- notify_callback mNotifyCb;
- data_callback mDataCb;
- data_callback_timestamp mDataCbTimestamp;
+ camera_notify_callback mNotifyCb;
+ camera_data_callback mDataCb;
+ camera_data_timestamp_callback mDataCbTimestamp;
+ camera_request_memory mGetMemoryCb;
void *mCallbackCookie;
int32_t mMsgEnabled;
@@ -210,6 +205,9 @@ private:
int mPostViewSize;
Vector<Size> mSupportedPreviewSizes;
+
+ camera_device_t *mHalDevice;
+ static gralloc_module_t const* mGrallocHal;
};
}; // namespace android