Camera-Unified HAL changes for 7x27a
Change-Id: Ie6f7fb08d38c29f72a82166503b3bdd8f7e29ac5
diff --git a/Android.mk b/Android.mk
index 3c9fe11..3c3ff99 100755
--- a/Android.mk
+++ b/Android.mk
@@ -14,11 +14,18 @@
LOCAL_CFLAGS:= -DDLOPEN_LIBMMCAMERA=$(DLOPEN_LIBMMCAMERA)
+#define BUILD_UNIFIED_CODE
+BUILD_UNIFIED_CODE := FALSE
+
+ifeq ($(call is-board-platform,msm7627a),true)
+LOCAL_CFLAGS+= -DVFE_7X27A
+endif
+
ifeq ($(strip $(TARGET_USES_ION)),true)
LOCAL_CFLAGS += -DUSE_ION
endif
ifeq ($(call is-board-platform,msm8960),true)
-MM_CAM_FILES:= \
+ MM_CAM_FILES:= \
mm_camera_interface2.c \
mm_camera_stream.c \
mm_camera_channel.c \
@@ -28,6 +35,20 @@
mm_omx_jpeg_encoder.c \
mm_camera_sock.c
endif
+ifeq ($(call is-board-platform,msm7627a),true)
+ifeq ($(BUILD_UNIFIED_CODE), true)
+ MM_CAM_FILES:= \
+ mm_camera_interface2.c \
+ mm_camera_stream.c \
+ mm_camera_channel.c \
+ mm_camera.c \
+ mm_camera_poll_thread.c \
+ mm_camera_notify.c mm_camera_helper.c \
+ mm_omx_jpeg_encoder.c \
+ mm_camera_sock.c
+
+endif
+endif
LOCAL_CFLAGS+= -DHW_ENCODE
@@ -40,6 +61,14 @@
QCameraHWI_Record.cpp QCameraHWI_Still.cpp \
QCameraHWI_Mem.cpp QCameraHWI_Display.cpp \
QCameraStream.cpp QualcommCamera2.cpp
+else ifeq ($(BUILD_UNIFIED_CODE), true)
+ ifeq ($(call is-board-platform,msm7627a),true)
+ LOCAL_HAL_FILES := QCameraHAL.cpp QCameraHWI_Parm.cpp\
+ QCameraHWI.cpp QCameraHWI_Preview_7x27A.cpp \
+ QCameraHWI_Record_7x27A.cpp QCameraHWI_Still.cpp \
+ QCameraHWI_Mem.cpp QCameraHWI_Display.cpp \
+ QCameraStream.cpp QualcommCamera2.cpp
+ endif
else
LOCAL_HAL_FILES := QualcommCamera.cpp QualcommCameraHardware.cpp
MM_CAM_FILES:=
@@ -74,8 +103,12 @@
ifeq ($(call is-board-platform,msm8960),true)
LOCAL_C_INCLUDES+= $(TARGET_OUT_HEADERS)/mm-core/omxcore
LOCAL_C_INCLUDES+= $(TARGET_OUT_HEADERS)/mm-still/mm-omx
+else ifeq ($(BUILD_UNIFIED_CODE), true)
+ ifeq ($(call is-board-platform,msm7627a),true)
+ LOCAL_C_INCLUDES+= $(TARGET_OUT_HEADERS)/mm-core/omxcore
+ LOCAL_C_INCLUDES+= $(TARGET_OUT_HEADERS)/mm-still/mm-omx
+ endif
endif
-
LOCAL_C_INCLUDES+= $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include/media
LOCAL_C_INCLUDES+= $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
@@ -87,8 +120,12 @@
ifeq ($(call is-board-platform,msm8960),true)
LOCAL_SHARED_LIBRARIES:= libutils libui libcamera_client liblog libcutils libmmjpeg libmmstillomx libimage-jpeg-enc-omx-comp
+else ifeq ($(BUILD_UNIFIED_CODE), true)
+ ifeq ($(call is-board-platform,msm7627a),true)
+ LOCAL_SHARED_LIBRARIES:= libutils libui libcamera_client liblog libcutils libmmjpeg libmmstillomx libimage-jpeg-enc-omx-comp
+ endif
else
-LOCAL_SHARED_LIBRARIES:= libutils libui libcamera_client liblog libcutils libmmjpeg
+ LOCAL_SHARED_LIBRARIES:= libutils libui libcamera_client liblog libcutils libmmjpeg
endif
LOCAL_SHARED_LIBRARIES+= libgenlock libbinder
diff --git a/QCameraHWI.h b/QCameraHWI.h
index 5c5661f..292881c 100755
--- a/QCameraHWI.h
+++ b/QCameraHWI.h
@@ -668,6 +668,7 @@
bool mSendMetaData;
bool mFullLiveshotEnabled;
bool mRecordingHint;
+ bool mStartRecording;
int mHdrMode;
/*for histogram*/
diff --git a/QCameraHWI_Parm.cpp b/QCameraHWI_Parm.cpp
index 373767e..fb91705 100755
--- a/QCameraHWI_Parm.cpp
+++ b/QCameraHWI_Parm.cpp
@@ -135,6 +135,7 @@
{ 6144, 240, 160 },
{ 5006, 176, 144 },
};
+#ifndef VFE_7X27A
static camera_size_type jpeg_thumbnail_sizes[] = {
{ 1920, 1088}, //1080p
{ 1280, 720}, // 720P, reserved
@@ -167,7 +168,6 @@
{ 240, 160}, // SQVGA
{ 176, 144}, // QCIF
};
-
static camera_size_type supported_video_sizes[] = {
{ 1920, 1088},// 1080p
{ 1280, 720}, // 720p
@@ -179,6 +179,62 @@
{ 320, 240}, // QVGA
{ 176, 144}, // QCIF
};
+#else
+ static camera_size_type jpeg_thumbnail_sizes[] = {
+ { 1920, 1088}, //1080p
+ { 1280, 720}, // 720P, reserved
+ { 800, 480}, // WVGA
+ { 864, 480},
+ { 768, 432},
+ { 720, 480},
+ { 640, 480}, // VGA
+ { 576, 432},
+ { 480, 320}, // HVGA
+ { 432, 240}, //WQVGA
+ { 384, 288},
+ { 352, 288}, // CIF
+ { 320, 240}, // QVGA
+ { 240, 160}, // SQVGA
+ { 176, 144}, // QCIF
+ {0,0}
+};
+
+static camera_size_type default_preview_sizes[] = {
+ { 1920, 1088}, //1080p
+ { 1280, 720}, // 720P, reserved
+ { 800, 480}, // WVGA
+ { 864, 480},
+ { 768, 432},
+ { 720, 480},
+ { 640, 480}, // VGA
+ { 576, 432},
+ { 480, 320}, // HVGA
+ { 432, 240}, //WQVGA
+ { 384, 288},
+ { 352, 288}, // CIF
+ { 320, 240}, // QVGA
+ { 240, 160}, // SQVGA
+ { 176, 144}, // QCIF
+};
+
+static camera_size_type supported_video_sizes[] = {
+ { 1920, 1088},// 1080p
+ { 1280, 720}, // 720p
+ { 800, 480}, // WVGA
+ { 864, 480},
+ { 768, 432},
+ { 720, 480}, // 480p
+ { 640, 480}, // VGA
+ { 576, 432},
+ { 480, 320}, // HVGA
+ { 432, 240}, //WQVGA
+ { 384, 288},
+ { 352, 288}, // CIF
+ { 320, 240}, // QVGA
+ { 240, 160}, // SQVGA
+ { 176, 144}, // QCIF
+};
+#endif
#define SUPPORTED_VIDEO_SIZES_COUNT (sizeof(supported_video_sizes)/sizeof(camera_size_type))
static struct camera_size_type zsl_picture_sizes[] = {
@@ -208,11 +264,17 @@
{ 320, 240}, // QVGA
{ 176, 144} // QCIF
};
-
+#ifndef VFE_7X27A
static camera_size_type hfr_sizes[] = {
{ 800, 480}, // WVGA
{ 640, 480} // VGA
};
+#else
+ static camera_size_type hfr_sizes[] = {
+ { 432, 240}, //WQVGA
+ { 320, 240} //QVGA
+};
+#endif
static int iso_speed_values[] = {
0, 1, 100, 200, 400, 800, 1600
@@ -1952,15 +2014,22 @@
status_t QCameraHardwareInterface::setSelectableZoneAf(const CameraParameters& params)
{
LOGE("%s",__func__);
+ status_t rc = NO_ERROR;
if(mHasAutoFocusSupport) {
const char *str = params.get(CameraParameters::KEY_SELECTABLE_ZONE_AF);
if (str != NULL) {
int32_t value = attr_lookup(selectable_zone_af, sizeof(selectable_zone_af) / sizeof(str_map), str);
if (value != NOT_FOUND) {
- mParameters.set(CameraParameters::KEY_SELECTABLE_ZONE_AF, str);
- bool ret = native_set_parms(MM_CAMERA_PARM_FOCUS_RECT, sizeof(value),
- (void *)&value);
- return ret ? NO_ERROR : UNKNOWN_ERROR;
+ rc = cam_config_is_parm_supported(mCameraId, MM_CAMERA_PARM_FOCUS_RECT);
+ if(!rc) {
+ LOGE("SelectableZoneAF is not supported for this sensor");
+ return NO_ERROR;
+ }else {
+ mParameters.set(CameraParameters::KEY_SELECTABLE_ZONE_AF, str);
+ bool ret = native_set_parms(MM_CAMERA_PARM_FOCUS_RECT, sizeof(value),
+ (void *)&value);
+ return ret ? NO_ERROR : UNKNOWN_ERROR;
+ }
}
}
LOGE("Invalid selectable zone af value: %s", (str == NULL) ? "NULL" : str);
diff --git a/QCameraHWI_Preview_7x27A.cpp b/QCameraHWI_Preview_7x27A.cpp
new file mode 100644
index 0000000..165206a
--- /dev/null
+++ b/QCameraHWI_Preview_7x27A.cpp
@@ -0,0 +1,815 @@
+/*
+** Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+/*#error uncomment this for compiler test!*/
+
+#define LOG_NDEBUG 0
+#define LOG_NIDEBUG 0
+#define LOG_TAG "QCameraHWI_Preview"
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include "QCameraHAL.h"
+#include "QCameraHWI.h"
+#include <gralloc_priv.h>
+#include <genlock.h>
+
+#define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
+
+/* QCameraHWI_Preview class implementation goes here*/
+/* following code implement the preview mode's image capture & display logic of this class*/
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+// Preview Callback
+// ---------------------------------------------------------------------------
+static void preview_notify_cb(mm_camera_ch_data_buf_t *frame,
+ void *user_data)
+{
+ QCameraStream_preview *pme = (QCameraStream_preview *)user_data;
+ mm_camera_ch_data_buf_t *bufs_used = 0;
+ LOGV("%s: E", __func__);
+ /* for peview data, there is no queue, so directly use*/
+ if(pme==NULL) {
+ LOGE("%s: X : Incorrect cookie",__func__);
+ /*Call buf done*/
+ return;
+ }
+
+ pme->processPreviewFrame(frame);
+ LOGV("%s: X", __func__);
+}
+
+status_t QCameraStream_preview::setPreviewWindow(preview_stream_ops_t* window)
+{
+ status_t retVal = NO_ERROR;
+ LOGE(" %s: E ", __FUNCTION__);
+ if( window == NULL) {
+ LOGW(" Setting NULL preview window ");
+ /* TODO: Current preview window will be invalidated.
+ * Release all the buffers back */
+ // relinquishBuffers();
+ }
+ mDisplayLock.lock();
+ mPreviewWindow = window;
+ mDisplayLock.unlock();
+ LOGV(" %s : X ", __FUNCTION__ );
+ return retVal;
+}
+
+status_t QCameraStream_preview::getBufferFromSurface() {
+ int err = 0;
+ int numMinUndequeuedBufs = 0;
+ int format = 0;
+ status_t ret = NO_ERROR;
+
+ LOGI(" %s : E ", __FUNCTION__);
+
+ if( mPreviewWindow == NULL) {
+ LOGE("%s: mPreviewWindow = NULL", __func__);
+ return INVALID_OPERATION;
+ }
+ cam_ctrl_dimension_t dim;
+
+ //mDisplayLock.lock();
+ cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION,&dim);
+
+ format = mHalCamCtrl->getPreviewFormatInfo().Hal_format;
+ if(ret != NO_ERROR) {
+ LOGE("%s: display format %d is not supported", __func__, dim.prev_format);
+ goto end;
+ }
+ numMinUndequeuedBufs = 0;
+ if(mPreviewWindow->get_min_undequeued_buffer_count) {
+ err = mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow, &numMinUndequeuedBufs);
+ if (err != 0) {
+ LOGE("get_min_undequeued_buffer_count failed: %s (%d)",
+ strerror(-err), -err);
+ ret = UNKNOWN_ERROR;
+ goto end;
+ }
+ }
+ mHalCamCtrl->mPreviewMemoryLock.lock();
+ mHalCamCtrl->mPreviewMemory.buffer_count = kPreviewBufferCount + numMinUndequeuedBufs;;
+ err = mPreviewWindow->set_buffer_count(mPreviewWindow, mHalCamCtrl->mPreviewMemory.buffer_count );
+ if (err != 0) {
+ LOGE("set_buffer_count failed: %s (%d)",
+ strerror(-err), -err);
+ ret = UNKNOWN_ERROR;
+ goto end;
+ }
+ err = mPreviewWindow->set_buffers_geometry(mPreviewWindow,
+ dim.display_width, dim.display_height, format);
+ if (err != 0) {
+ LOGE("set_buffers_geometry failed: %s (%d)",
+ strerror(-err), -err);
+ ret = UNKNOWN_ERROR;
+ goto end;
+ }
+ err = mPreviewWindow->set_usage(mPreviewWindow,
+ GRALLOC_USAGE_PRIVATE_ADSP_HEAP |
+ GRALLOC_USAGE_PRIVATE_UNCACHED);
+ if(err != 0) {
+ /* set_usage error out */
+ LOGE("%s: set_usage rc = %d", __func__, err);
+ ret = UNKNOWN_ERROR;
+ goto end;
+ }
+ for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) {
+ int stride;
+ err = mPreviewWindow->dequeue_buffer(mPreviewWindow,
+ &mHalCamCtrl->mPreviewMemory.buffer_handle[cnt],
+ &mHalCamCtrl->mPreviewMemory.stride[cnt]);
+ if(!err) {
+ err = mPreviewWindow->lock_buffer(this->mPreviewWindow,
+ mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
+
+ // lock the buffer using genlock
+ LOGD("%s: camera call genlock_lock", __FUNCTION__);
+ if (GENLOCK_NO_ERROR != genlock_lock_buffer((native_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]),
+ GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
+ LOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__);
+ mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED;
+ mHalCamCtrl->mPreviewMemoryLock.unlock();
+ return -EINVAL;
+ }
+ mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_LOCKED;
+ } else
+ LOGE("%s: dequeue_buffer idx = %d err = %d", __func__, cnt, err);
+
+ LOGE("%s: dequeue buf: %u\n", __func__, (unsigned int)mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
+
+ if(err != 0) {
+ LOGE("%s: dequeue_buffer failed: %s (%d)", __func__,
+ strerror(-err), -err);
+ ret = UNKNOWN_ERROR;
+ for(int i = 0; i < cnt; i++) {
+ LOGD("%s: camera call genlock_unlock", __FUNCTION__);
+ if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[i]) {
+ if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *)
+ (*(mHalCamCtrl->mPreviewMemory.buffer_handle[i])))) {
+ LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
+ mHalCamCtrl->mPreviewMemoryLock.unlock();
+ return -EINVAL;
+ }
+ }
+ err = mPreviewWindow->cancel_buffer(mPreviewWindow,
+ mHalCamCtrl->mPreviewMemory.buffer_handle[i]);
+ mHalCamCtrl->mPreviewMemory.buffer_handle[i] = NULL;
+ mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_UNLOCKED;
+ }
+ goto end;
+ }
+ mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt] =
+ (struct private_handle_t *)(*mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
+ mHalCamCtrl->mPreviewMemory.camera_memory[cnt] =
+ mHalCamCtrl->mGetMemory(mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd,
+ mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size, 1, (void *)this);
+ LOGE("%s: idx = %d, fd = %d, size = %d, offset = %d", __func__,
+ cnt, mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd,
+ mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size,
+ mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->offset);
+ }
+
+
+ memset(&mHalCamCtrl->mMetadata, 0, sizeof(mHalCamCtrl->mMetadata));
+ memset(mHalCamCtrl->mFace, 0, sizeof(mHalCamCtrl->mFace));
+
+ LOGI(" %s : X ",__FUNCTION__);
+end:
+ //mDisplayLock.unlock();
+ mHalCamCtrl->mPreviewMemoryLock.unlock();
+
+ return NO_ERROR;
+}
+
+status_t QCameraStream_preview::putBufferToSurface() {
+ int err = 0;
+ status_t ret = NO_ERROR;
+
+ LOGI(" %s : E ", __FUNCTION__);
+
+ //mDisplayLock.lock();
+ mHalCamCtrl->mPreviewMemoryLock.lock();
+ for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) {
+ mHalCamCtrl->mPreviewMemory.camera_memory[cnt]->release(mHalCamCtrl->mPreviewMemory.camera_memory[cnt]);
+ if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[cnt]) {
+ LOGD("%s: camera call genlock_unlock", __FUNCTION__);
+ if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *)
+ (*(mHalCamCtrl->mPreviewMemory.buffer_handle[cnt])))) {
+ LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
+ mHalCamCtrl->mPreviewMemoryLock.unlock();
+ return -EINVAL;
+ } else {
+ mHalCamCtrl->mPreviewMemory.local_flag[cnt] = BUFFER_UNLOCKED;
+ }
+ }
+ err = mPreviewWindow->cancel_buffer(mPreviewWindow, mHalCamCtrl->mPreviewMemory.buffer_handle[cnt]);
+ LOGE(" put buffer %d successfully", cnt);
+ }
+ memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory));
+ mHalCamCtrl->mPreviewMemoryLock.unlock();
+ //mDisplayLock.unlock();
+ LOGI(" %s : X ",__FUNCTION__);
+ return NO_ERROR;
+}
+
+void QCameraStream_preview::notifyROIEvent(fd_roi_t roi)
+{
+ int faces_detected = roi.rect_num;
+ if(faces_detected > MAX_ROI)
+ faces_detected = MAX_ROI;
+ LOGI("%s, width = %d height = %d", __func__,
+ mHalCamCtrl->mDimension.display_width,
+ mHalCamCtrl->mDimension.display_height);
+ mDisplayLock.lock();
+ for (int i = 0; i < faces_detected; i++) {
+ mHalCamCtrl->mFace[i].rect[0] =
+ roi.faces[i].x*2000/mHalCamCtrl->mDimension.display_width - 1000;
+ mHalCamCtrl->mFace[i].rect[1] =
+ roi.faces[i].y*2000/mHalCamCtrl->mDimension.display_height - 1000;
+ mHalCamCtrl->mFace[i].rect[2] =
+ roi.faces[i].dx*2000/mHalCamCtrl->mDimension.display_width;
+ mHalCamCtrl->mFace[i].rect[3] =
+ roi.faces[i].dy*2000/mHalCamCtrl->mDimension.display_height;
+ }
+ mHalCamCtrl->mMetadata.number_of_faces = faces_detected;
+ mHalCamCtrl->mMetadata.faces = mHalCamCtrl->mFace;
+ mDisplayLock.unlock();
+}
+
+status_t QCameraStream_preview::initDisplayBuffers()
+{
+ status_t ret = NO_ERROR;
+ int width = 0; /* width of channel */
+ int height = 0; /* height of channel */
+ uint32_t frame_len = 0; /* frame planner length */
+ int buffer_num = 4; /* number of buffers for display */
+ const char *pmem_region;
+ uint8_t num_planes = 0;
+ uint32_t planes[VIDEO_MAX_PLANES];
+
+ cam_ctrl_dimension_t dim;
+
+ LOGE("%s:BEGIN",__func__);
+ memset(&mHalCamCtrl->mMetadata, 0, sizeof(camera_frame_metadata_t));
+ mHalCamCtrl->mPreviewMemoryLock.lock();
+ memset(&mHalCamCtrl->mPreviewMemory, 0, sizeof(mHalCamCtrl->mPreviewMemory));
+ mHalCamCtrl->mPreviewMemoryLock.unlock();
+ memset(&mNotifyBuffer, 0, sizeof(mNotifyBuffer));
+
+ /* get preview size, by qury mm_camera*/
+ memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
+
+ memset(&(this->mDisplayStreamBuf),0, sizeof(this->mDisplayStreamBuf));
+
+ ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
+ if (MM_CAMERA_OK != ret) {
+ LOGE("%s: error - can't get camera dimension!", __func__);
+ LOGE("%s: X", __func__);
+ return BAD_VALUE;
+ }else {
+ width = dim.display_width,
+ height = dim.display_height;
+ }
+
+ ret = getBufferFromSurface();
+ if(ret != NO_ERROR) {
+ LOGE("%s: cannot get memory from surface texture client, ret = %d", __func__, ret);
+ return ret;
+ }
+
+ /* set 4 buffers for display */
+ memset(&mDisplayStreamBuf, 0, sizeof(mDisplayStreamBuf));
+ mHalCamCtrl->mPreviewMemoryLock.lock();
+ this->mDisplayStreamBuf.num = mHalCamCtrl->mPreviewMemory.buffer_count;
+ this->myMode=myMode; /*Need to assign this in constructor after translating from mask*/
+ num_planes = 2;
+ planes[0] = dim.display_frame_offset.mp[0].len;
+ planes[1] = dim.display_frame_offset.mp[1].len;
+ this->mDisplayStreamBuf.frame_len = dim.display_frame_offset.frame_len;
+
+ mDisplayBuf.preview.buf.mp = new mm_camera_mp_buf_t[mDisplayStreamBuf.num];
+ if (!mDisplayBuf.preview.buf.mp) {
+ LOGE("%s Error allocating memory for mplanar struct ", __func__);
+ }
+ memset(mDisplayBuf.preview.buf.mp, 0,
+ mDisplayStreamBuf.num * sizeof(mm_camera_mp_buf_t));
+
+ /*allocate memory for the buffers*/
+ void *vaddr = NULL;
+ for(int i = 0; i < mDisplayStreamBuf.num; i++){
+ if (mHalCamCtrl->mPreviewMemory.private_buffer_handle[i] == NULL)
+ continue;
+ mDisplayStreamBuf.frame[i].fd = mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->fd;
+ mDisplayStreamBuf.frame[i].cbcr_off = planes[0];
+ mDisplayStreamBuf.frame[i].y_off = 0;
+ mDisplayStreamBuf.frame[i].path = OUTPUT_TYPE_P;
+ mHalCamCtrl->mPreviewMemory.addr_offset[i] =
+ mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->offset;
+ mDisplayStreamBuf.frame[i].buffer =
+ (long unsigned int)mHalCamCtrl->mPreviewMemory.camera_memory[i]->data;
+
+ LOGE("%s: idx = %d, fd = %d, size = %d, cbcr_offset = %d, y_offset = %d, offset = %d, vaddr = 0x%x",
+ __func__, i,
+ mDisplayStreamBuf.frame[i].fd,
+ mHalCamCtrl->mPreviewMemory.private_buffer_handle[i]->size,
+ mDisplayStreamBuf.frame[i].cbcr_off,
+ mDisplayStreamBuf.frame[i].y_off,
+ mHalCamCtrl->mPreviewMemory.addr_offset[i],
+ (uint32_t)mDisplayStreamBuf.frame[i].buffer);
+
+
+ mDisplayBuf.preview.buf.mp[i].frame = mDisplayStreamBuf.frame[i];
+ mDisplayBuf.preview.buf.mp[i].frame_offset = mHalCamCtrl->mPreviewMemory.addr_offset[i];
+ mDisplayBuf.preview.buf.mp[i].num_planes = num_planes;
+
+ /* Plane 0 needs to be set seperately. Set other planes
+ * in a loop. */
+ mDisplayBuf.preview.buf.mp[i].planes[0].length = planes[0];
+ mDisplayBuf.preview.buf.mp[i].planes[0].m.userptr = mDisplayStreamBuf.frame[i].fd;
+ mDisplayBuf.preview.buf.mp[i].planes[0].data_offset = 0;
+ mDisplayBuf.preview.buf.mp[i].planes[0].reserved[0] =
+ mDisplayBuf.preview.buf.mp[i].frame_offset;
+ for (int j = 1; j < num_planes; j++) {
+ mDisplayBuf.preview.buf.mp[i].planes[j].length = planes[j];
+ mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr =
+ mDisplayStreamBuf.frame[i].fd;
+ mDisplayBuf.preview.buf.mp[i].planes[j].data_offset = 0;
+ mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0] =
+ mDisplayBuf.preview.buf.mp[i].planes[j-1].reserved[0] +
+ mDisplayBuf.preview.buf.mp[i].planes[j-1].length;
+ }
+
+ for (int j = 0; j < num_planes; j++) {
+ LOGE("Planes: %d length: %d userptr: %lu offset: %d\n",
+ j, mDisplayBuf.preview.buf.mp[i].planes[j].length,
+ mDisplayBuf.preview.buf.mp[i].planes[j].m.userptr,
+ mDisplayBuf.preview.buf.mp[i].planes[j].reserved[0]);
+ }
+
+ }/*end of for loop*/
+
+ /* register the streaming buffers for the channel*/
+ mDisplayBuf.ch_type = MM_CAMERA_CH_PREVIEW;
+ mDisplayBuf.preview.num = mDisplayStreamBuf.num;
+ mHalCamCtrl->mPreviewMemoryLock.unlock();
+ LOGE("%s:END",__func__);
+ return NO_ERROR;
+
+end:
+ if (MM_CAMERA_OK == ret ) {
+ LOGV("%s: X - NO_ERROR ", __func__);
+ return NO_ERROR;
+ }
+
+ LOGV("%s: out of memory clean up", __func__);
+ /* release the allocated memory */
+
+ LOGV("%s: X - BAD_VALUE ", __func__);
+ return BAD_VALUE;
+}
+
+void QCameraStream_preview::dumpFrameToFile(struct msm_frame* newFrame)
+{
+ int32_t enabled = 0;
+ int frm_num;
+ uint32_t skip_mode;
+ char value[PROPERTY_VALUE_MAX];
+ char buf[32];
+ int w, h;
+ static int count = 0;
+ cam_ctrl_dimension_t dim;
+ int file_fd;
+ int rc = 0;
+ int len;
+ unsigned long addr;
+ unsigned long * tmp = (unsigned long *)newFrame->buffer;
+ addr = *tmp;
+ status_t ret = cam_config_get_parm(mHalCamCtrl->mCameraId,
+ MM_CAMERA_PARM_DIMENSION, &dim);
+
+ w = dim.display_width;
+ h = dim.display_height;
+ len = (w * h)*3/2;
+ count++;
+ if(count < 100) {
+ snprintf(buf, sizeof(buf), "/data/mzhu%d.yuv", count);
+ file_fd = open(buf, O_RDWR | O_CREAT, 0777);
+
+ rc = write(file_fd, (const void *)addr, len);
+ LOGE("%s: file='%s', vaddr_old=0x%x, addr_map = 0x%p, len = %d, rc = %d",
+ __func__, buf, (uint32_t)newFrame->buffer, (void *)addr, len, rc);
+ close(file_fd);
+ LOGE("%s: dump %s, rc = %d, len = %d", __func__, buf, rc, len);
+ }
+}
+
+status_t QCameraStream_preview::processPreviewFrame(mm_camera_ch_data_buf_t *frame)
+{
+ LOGV("%s",__func__);
+ int err = 0;
+ int msgType = 0;
+ camera_memory_t *data = NULL;
+ camera_frame_metadata_t *metadata = NULL;
+
+ Mutex::Autolock lock(mStopCallbackLock);
+ if(!mActive) {
+ LOGE("Preview Stopped. Returning callback");
+ return NO_ERROR;
+ }
+ if(mHalCamCtrl==NULL) {
+ LOGE("%s: X: HAL control object not set",__func__);
+ /*Call buf done*/
+ return BAD_VALUE;
+ }
+
+ mHalCamCtrl->mCallbackLock.lock();
+ camera_data_timestamp_callback rcb = mHalCamCtrl->mDataCbTimestamp;
+ void *rdata = mHalCamCtrl->mCallbackCookie;
+ mHalCamCtrl->mCallbackLock.unlock();
+
+ if (UNLIKELY(mHalCamCtrl->mDebugFps)) {
+ mHalCamCtrl->debugShowPreviewFPS();
+ }
+ //dumpFrameToFile(frame->def.frame);
+ mHalCamCtrl->dumpFrameToFile(frame->def.frame, HAL_DUMP_FRM_PREVIEW);
+
+ nsecs_t timeStamp = systemTime();
+
+ mHalCamCtrl->mPreviewMemoryLock.lock();
+ mNotifyBuffer[frame->def.idx] = *frame;
+ // mzhu fix me, need to check meta data also.
+
+ LOGI("Enqueue buf handle %p\n",
+ mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
+ LOGD("%s: camera call genlock_unlock", __FUNCTION__);
+ if (BUFFER_LOCKED == mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx]) {
+ if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t*)
+ (*mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]))) {
+ LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
+ mHalCamCtrl->mPreviewMemoryLock.unlock();
+ return -EINVAL;
+ } else {
+ mHalCamCtrl->mPreviewMemory.local_flag[frame->def.idx] = BUFFER_UNLOCKED;
+ }
+ } else {
+ LOGE("%s: buffer to be enqueued is not locked", __FUNCTION__);
+ mHalCamCtrl->mPreviewMemoryLock.unlock();
+ return -EINVAL;
+ }
+ err = this->mPreviewWindow->enqueue_buffer(this->mPreviewWindow,
+ (buffer_handle_t *)mHalCamCtrl->mPreviewMemory.buffer_handle[frame->def.idx]);
+ if(err != 0) {
+ LOGE("%s: enqueue_buffer failed, err = %d", __func__, err);
+ }
+ buffer_handle_t *buffer_handle = NULL;
+ int tmp_stride = 0;
+ err = this->mPreviewWindow->dequeue_buffer(this->mPreviewWindow,
+ &buffer_handle, &tmp_stride);
+ if (err == NO_ERROR && buffer_handle != NULL) {
+ err = this->mPreviewWindow->lock_buffer(this->mPreviewWindow, buffer_handle);
+ LOGD("%s: camera call genlock_lock", __FUNCTION__);
+ if (GENLOCK_FAILURE == genlock_lock_buffer((native_handle_t*)(*buffer_handle), GENLOCK_WRITE_LOCK,
+ GENLOCK_MAX_TIMEOUT)) {
+ LOGE("%s: genlock_lock_buffer(WRITE) failed", __FUNCTION__);
+ mHalCamCtrl->mPreviewMemoryLock.unlock();
+ return -EINVAL;
+ }
+ for(int i = 0; i < mHalCamCtrl->mPreviewMemory.buffer_count; i++) {
+ LOGD("h1: %p h2: %p\n", mHalCamCtrl->mPreviewMemory.buffer_handle[i], buffer_handle);
+ if(mHalCamCtrl->mPreviewMemory.buffer_handle[i] == buffer_handle) {
+ mm_camera_ch_data_buf_t tmp_frame;
+ mHalCamCtrl->mPreviewMemory.local_flag[i] = BUFFER_LOCKED;
+ if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mNotifyBuffer[i])) {
+ LOGD("BUF DONE FAILED");
+ mHalCamCtrl->mPreviewMemoryLock.unlock();
+ return BAD_VALUE;
+ }
+ break;
+ }
+ }
+ } else
+ LOGE("%s: error in dequeue_buffer, enqueue_buffer idx = %d, no free buffer now", __func__, frame->def.idx);
+ /* Save the last displayed frame. We'll be using it to fill the gap between
+ when preview stops and postview start during snapshot.*/
+ mLastQueuedFrame = &(mDisplayStreamBuf.frame[frame->def.idx]);
+ mHalCamCtrl->mPreviewMemoryLock.unlock();
+
+ mHalCamCtrl->mCallbackLock.lock();
+ camera_data_callback pcb = mHalCamCtrl->mDataCb;
+ mHalCamCtrl->mCallbackLock.unlock();
+ LOGD("Message enabled = 0x%x", mHalCamCtrl->mMsgEnabled);
+
+ if (pcb != NULL) {
+ //Sending preview callback if corresponding Msgs are enabled
+ if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
+ msgType |= CAMERA_MSG_PREVIEW_FRAME;
+ data = mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx];//mPreviewHeap->mBuffers[frame->def.idx];
+ } else {
+ data = NULL;
+ }
+ if(mHalCamCtrl->mMsgEnabled & CAMERA_MSG_PREVIEW_METADATA){
+ msgType |= CAMERA_MSG_PREVIEW_METADATA;
+ metadata = &mHalCamCtrl->mMetadata;
+ } else {
+ metadata = NULL;
+ }
+ if(msgType) {
+ mStopCallbackLock.unlock();
+ pcb(msgType, data, 0, metadata, mHalCamCtrl->mCallbackCookie);
+ }
+ LOGD("end of cb");
+ }
+ if(rcb != NULL)
+ {
+ if (mHalCamCtrl->mStoreMetaDataInFrame)
+ {
+ LOGE("sandeep:Metadata enabled");
+ mStopCallbackLock.unlock();
+ if(mHalCamCtrl->mStartRecording == true &&( mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME))
+ rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
+ mHalCamCtrl->mRecordingMemory.metadata_memory[frame->def.idx],
+ 0, mHalCamCtrl->mCallbackCookie);
+ }
+ else
+ {
+ LOGE("sandeep:MetaData is not enabled");
+ if(mHalCamCtrl->mStartRecording == true &&( mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME))
+ {
+ mStopCallbackLock.unlock();
+ rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
+ mHalCamCtrl->mPreviewMemory.camera_memory[frame->def.idx],
+ 0, mHalCamCtrl->mCallbackCookie);
+ }
+ }
+ }
+
+ /* Save the last displayed frame. We'll be using it to fill the gap between
+ when preview stops and postview start during snapshot.*/
+ //mLastQueuedFrame = frame->def.frame;
+/*
+ if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, frame))
+ {
+ LOGE("BUF DONE FAILED");
+ return BAD_VALUE;
+ }
+*/
+ return NO_ERROR;
+}
+
+// ---------------------------------------------------------------------------
+// QCameraStream_preview
+// ---------------------------------------------------------------------------
+
+QCameraStream_preview::
+QCameraStream_preview(int cameraId, camera_mode_t mode)
+ : QCameraStream(cameraId,mode),
+ mLastQueuedFrame(NULL)
+ {
+ mHalCamCtrl = NULL;
+ LOGE("%s: E", __func__);
+ LOGE("%s: X", __func__);
+ }
+// ---------------------------------------------------------------------------
+// QCameraStream_preview
+// ---------------------------------------------------------------------------
+
+QCameraStream_preview::~QCameraStream_preview() {
+ LOGV("%s: E", __func__);
+ if(mActive) {
+ stop();
+ }
+ if(mInit) {
+ release();
+ }
+ mInit = false;
+ mActive = false;
+ LOGV("%s: X", __func__);
+
+}
+// ---------------------------------------------------------------------------
+// QCameraStream_preview
+// ---------------------------------------------------------------------------
+
+status_t QCameraStream_preview::init() {
+
+ status_t ret = NO_ERROR;
+ LOGV("%s: E", __func__);
+
+ ret = QCameraStream::initChannel (mCameraId, MM_CAMERA_CH_PREVIEW_MASK);
+ if (NO_ERROR!=ret) {
+ LOGE("%s E: can't init native cammera preview ch\n",__func__);
+ return ret;
+ }
+
+ LOGE("Debug : %s : initChannel",__func__);
+ /* register a notify into the mmmm_camera_t object*/
+ (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
+ preview_notify_cb, MM_CAMERA_REG_BUF_CB_INFINITE, 0, this);
+ LOGE("Debug : %s : cam_evt_register_buf_notify",__func__);
+ buffer_handle_t *buffer_handle = NULL;
+ int tmp_stride = 0;
+ mInit = true;
+ return ret;
+}
+// ---------------------------------------------------------------------------
+// QCameraStream_preview
+// ---------------------------------------------------------------------------
+
+status_t QCameraStream_preview::start()
+{
+ LOGV("%s: E", __func__);
+ status_t ret = NO_ERROR;
+ mm_camera_reg_buf_t *reg_buf=&mDisplayBuf;
+
+ Mutex::Autolock lock(mStopCallbackLock);
+
+ /* call start() in parent class to start the monitor thread*/
+ //QCameraStream::start ();
+ setFormat(MM_CAMERA_CH_PREVIEW_MASK);
+
+ if(NO_ERROR!=initDisplayBuffers()){
+ return BAD_VALUE;
+ }
+ LOGE("Debug : %s : initDisplayBuffers",__func__);
+ ret = cam_config_prepare_buf(mCameraId, reg_buf);
+ LOGE("Debug : %s : cam_config_prepare_buf",__func__);
+ if(ret != MM_CAMERA_OK) {
+ LOGV("%s:reg preview buf err=%d\n", __func__, ret);
+ ret = BAD_VALUE;
+ }else
+ ret = NO_ERROR;
+
+ /* For preview, the OP_MODE we set is dependent upon whether we are
+ starting camera or camcorder. For snapshot, anyway we disable preview.
+ However, for ZSL we need to set OP_MODE to OP_MODE_ZSL and not
+ OP_MODE_VIDEO. We'll set that for now in CamCtrl. So in case of
+ ZSL we skip setting Mode here */
+
+ if (!(myMode & CAMERA_ZSL_MODE)) {
+ LOGE("Setting OP MODE to MM_CAMERA_OP_MODE_VIDEO");
+ mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_VIDEO;
+ ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE,
+ &op_mode);
+ LOGE("OP Mode Set");
+
+ if(MM_CAMERA_OK != ret) {
+ LOGE("%s: X :set mode MM_CAMERA_OP_MODE_VIDEO err=%d\n", __func__, ret);
+ return BAD_VALUE;
+ }
+ }else {
+ LOGE("Setting OP MODE to MM_CAMERA_OP_MODE_ZSL");
+ mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_ZSL;
+ ret = cam_config_set_parm (mCameraId, MM_CAMERA_PARM_OP_MODE,
+ &op_mode);
+ if(MM_CAMERA_OK != ret) {
+ LOGE("%s: X :set mode MM_CAMERA_OP_MODE_ZSL err=%d\n", __func__, ret);
+ return BAD_VALUE;
+ }
+ }
+
+ /* call mm_camera action start(...) */
+ LOGE("Starting Preview/Video Stream. ");
+ ret = cam_ops_action(mCameraId, TRUE, MM_CAMERA_OPS_PREVIEW, 0);
+
+ if (MM_CAMERA_OK != ret) {
+ LOGE ("%s: preview streaming start err=%d\n", __func__, ret);
+ return BAD_VALUE;
+ }
+
+ LOGE("Debug : %s : Preview streaming Started",__func__);
+ ret = NO_ERROR;
+
+ mActive = true;
+ LOGE("%s: X", __func__);
+ return NO_ERROR;
+ }
+
+
+// ---------------------------------------------------------------------------
+// QCameraStream_preview
+// ---------------------------------------------------------------------------
+ void QCameraStream_preview::stop() {
+ LOGE("%s: E", __func__);
+ int ret=MM_CAMERA_OK;
+
+ if(!mActive) {
+ return;
+ }
+ mActive = false;
+ Mutex::Autolock lock(mStopCallbackLock);
+ /* unregister the notify fn from the mmmm_camera_t object*/
+
+ /* call stop() in parent class to stop the monitor thread*/
+ ret = cam_ops_action(mCameraId, FALSE, MM_CAMERA_OPS_PREVIEW, 0);
+ if(MM_CAMERA_OK != ret) {
+ LOGE ("%s: camera preview stop err=%d\n", __func__, ret);
+ }
+ LOGE("Debug : %s : Preview streaming Stopped",__func__);
+ ret = cam_config_unprepare_buf(mCameraId, MM_CAMERA_CH_PREVIEW);
+ if(ret != MM_CAMERA_OK) {
+ LOGE("%s:Unreg preview buf err=%d\n", __func__, ret);
+ //ret = BAD_VALUE;
+ }
+
+ LOGE("Debug : %s : Buffer Unprepared",__func__);
+ if (mDisplayBuf.preview.buf.mp != NULL) {
+ delete[] mDisplayBuf.preview.buf.mp;
+ }
+ /*free camera_memory handles and return buffer back to surface*/
+ putBufferToSurface();
+
+ LOGE("%s: X", __func__);
+
+ }
+// ---------------------------------------------------------------------------
+// QCameraStream_preview
+// ---------------------------------------------------------------------------
+ void QCameraStream_preview::release() {
+
+ LOGE("%s : BEGIN",__func__);
+ int ret=MM_CAMERA_OK,i;
+
+ if(!mInit)
+ {
+ LOGE("%s : Stream not Initalized",__func__);
+ return;
+ }
+
+ if(mActive) {
+ this->stop();
+ }
+
+ ret= QCameraStream::deinitChannel(mCameraId, MM_CAMERA_CH_PREVIEW);
+ LOGE("Debug : %s : De init Channel",__func__);
+ if(ret != MM_CAMERA_OK) {
+ LOGE("%s:Deinit preview channel failed=%d\n", __func__, ret);
+ //ret = BAD_VALUE;
+ }
+
+ (void)cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
+ NULL,
+ (mm_camera_register_buf_cb_type_t)NULL,
+ NULL,
+ NULL);
+ mInit = false;
+ LOGE("%s: END", __func__);
+
+ }
+
+QCameraStream*
+QCameraStream_preview::createInstance(int cameraId,
+ camera_mode_t mode)
+{
+ QCameraStream* pme = new QCameraStream_preview(cameraId, mode);
+ return pme;
+}
+// ---------------------------------------------------------------------------
+// QCameraStream_preview
+// ---------------------------------------------------------------------------
+
+void QCameraStream_preview::deleteInstance(QCameraStream *p)
+{
+ if (p){
+ LOGV("%s: BEGIN", __func__);
+ p->release();
+ delete p;
+ p = NULL;
+ LOGV("%s: END", __func__);
+ }
+}
+
+
+/* Temp helper function */
+void *QCameraStream_preview::getLastQueuedFrame(void)
+{
+ return mLastQueuedFrame;
+}
+
+/* Set preview pause flag */
+void QCameraStream_preview::setPreviewPauseFlag(bool bPaused)
+{
+ mbPausedBySnapshot = bPaused;
+}
+
+// ---------------------------------------------------------------------------
+// No code beyone this line
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/QCameraHWI_Record_7x27A.cpp b/QCameraHWI_Record_7x27A.cpp
new file mode 100644
index 0000000..d36fce1
--- /dev/null
+++ b/QCameraHWI_Record_7x27A.cpp
@@ -0,0 +1,721 @@
+/*
+** Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+/*#error uncomment this for compiler test!*/
+
+#define LOG_NDEBUG 0
+#define LOG_NIDEBUG 0
+#define LOG_TAG "QCameraHWI_Record"
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include <cutils/properties.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include "QCameraStream.h"
+
+
+#define LIKELY(exp) __builtin_expect(!!(exp), 1)
+#define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
+
+/* QCameraStream_record class implementation goes here*/
+/* following code implement the video streaming capture & encoding logic of this class*/
+// ---------------------------------------------------------------------------
+// QCameraStream_record createInstance()
+// ---------------------------------------------------------------------------
+namespace android {
+
+
+QCameraStream* QCameraStream_record::createInstance(int cameraId,
+ camera_mode_t mode)
+{
+ LOGV("%s: BEGIN", __func__);
+ QCameraStream* pme = new QCameraStream_record(cameraId, mode);
+ LOGV("%s: END", __func__);
+ return pme;
+}
+
+// ---------------------------------------------------------------------------
+// QCameraStream_record deleteInstance()
+// ---------------------------------------------------------------------------
+void QCameraStream_record::deleteInstance(QCameraStream *ptr)
+{
+ LOGV("%s: BEGIN", __func__);
+ if (ptr){
+ ptr->release();
+ delete ptr;
+ ptr = NULL;
+ }
+ LOGV("%s: END", __func__);
+}
+
+// ---------------------------------------------------------------------------
+// QCameraStream_record Constructor
+// ---------------------------------------------------------------------------
+QCameraStream_record::QCameraStream_record(int cameraId,
+ camera_mode_t mode)
+ :QCameraStream(cameraId,mode),
+ mDebugFps(false)
+{
+ mHalCamCtrl = NULL;
+ char value[PROPERTY_VALUE_MAX];
+ LOGV("%s: BEGIN", __func__);
+
+ property_get("persist.debug.sf.showfps", value, "0");
+ mDebugFps = atoi(value);
+
+ LOGV("%s: END", __func__);
+}
+
+// ---------------------------------------------------------------------------
+// QCameraStream_record Destructor
+// ---------------------------------------------------------------------------
+QCameraStream_record::~QCameraStream_record() {
+ LOGV("%s: BEGIN", __func__);
+ if(mActive) {
+ stop();
+ }
+ if(mInit) {
+ release();
+ }
+ mInit = false;
+ mActive = false;
+ LOGV("%s: END", __func__);
+
+}
+
+// ---------------------------------------------------------------------------
+// QCameraStream_record Callback from mm_camera
+// ---------------------------------------------------------------------------
+static void record_notify_cb(mm_camera_ch_data_buf_t *bufs_new,
+ void *user_data)
+{
+ QCameraStream_record *pme = (QCameraStream_record *)user_data;
+ mm_camera_ch_data_buf_t *bufs_used = 0;
+ LOGV("%s: BEGIN", __func__);
+
+ /*
+ * Call Function Process Video Data
+ */
+ pme->processRecordFrame(bufs_new);
+ LOGV("%s: END", __func__);
+}
+
+// ---------------------------------------------------------------------------
+// QCameraStream_record
+// ---------------------------------------------------------------------------
+status_t QCameraStream_record::init()
+{
+ status_t ret = NO_ERROR;
+ LOGV("%s: BEGIN", __func__);
+#if 0
+ /*
+ * Acquiring Video Channel
+ */
+ ret = QCameraStream::initChannel (mCameraId, MM_CAMERA_CH_VIDEO_MASK);
+ if (NO_ERROR!=ret) {
+ LOGE("%s ERROR: Can't init native cammera preview ch\n",__func__);
+ return ret;
+ }
+
+ /*
+ * Register the Callback with camera
+ */
+ (void) cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO,
+ record_notify_cb,
+ this);
+#endif
+ mInit = true;
+ LOGV("%s: END", __func__);
+ return ret;
+}
+// ---------------------------------------------------------------------------
+// QCameraStream_record
+// ---------------------------------------------------------------------------
+
+status_t QCameraStream_record::start()
+{
+ status_t ret = NO_ERROR;
+ LOGE("%s: BEGIN", __func__);
+ mHalCamCtrl->mStartRecording = true;
+ ret = initEncodeBuffers();
+ if (NO_ERROR!=ret) {
+ LOGE("%s ERROR: Buffer Allocation Failed\n",__func__);
+ return ret;
+ }
+
+#if 0
+ Mutex::Autolock lock(mStopCallbackLock);
+ if(!mInit) {
+ LOGE("%s ERROR: Record buffer not registered",__func__);
+ return BAD_VALUE;
+ }
+
+ setFormat(MM_CAMERA_CH_VIDEO_MASK);
+ //mRecordFreeQueueLock.lock();
+ //mRecordFreeQueue.clear();
+ //mRecordFreeQueueLock.unlock();
+ /*
+ * Allocating Encoder Frame Buffers
+ */
+ ret = initEncodeBuffers();
+ if (NO_ERROR!=ret) {
+ LOGE("%s ERROR: Buffer Allocation Failed\n",__func__);
+ return ret;
+ }
+
+ ret = cam_config_prepare_buf(mCameraId, &mRecordBuf);
+ if(ret != MM_CAMERA_OK) {
+ LOGV("%s ERROR: Reg Record buf err=%d\n", __func__, ret);
+ ret = BAD_VALUE;
+ }else{
+ ret = NO_ERROR;
+ }
+
+ /*
+ * Start Video Streaming
+ */
+ ret = cam_ops_action(mCameraId, TRUE, MM_CAMERA_OPS_VIDEO, 0);
+ if (MM_CAMERA_OK != ret) {
+ LOGE ("%s ERROR: Video streaming start err=%d\n", __func__, ret);
+ ret = BAD_VALUE;
+ }else{
+ LOGE("%s : Video streaming Started",__func__);
+ ret = NO_ERROR;
+ }
+ mActive = true;
+#endif
+ LOGV("%s: END", __func__);
+ return ret;
+}
+
+// ---------------------------------------------------------------------------
+// QCameraStream_record
+// ---------------------------------------------------------------------------
+void QCameraStream_record::stop()
+{
+ status_t ret = NO_ERROR;
+ LOGE("%s: BEGIN", __func__);
+ mHalCamCtrl->mStartRecording = false;
+#if 0
+ if(!mActive) {
+ LOGE("%s : Record stream not started",__func__);
+ return;
+ }
+ mActive = false;
+ Mutex::Autolock lock(mStopCallbackLock);
+#if 0 //mzhu, when stop recording, all frame will be dirty. no need to queue frame back to kernel any more
+ mRecordFreeQueueLock.lock();
+ while(!mRecordFreeQueue.isEmpty()) {
+ LOGV("%s : Pre-releasing of Encoder buffers!\n", __FUNCTION__);
+ mm_camera_ch_data_buf_t releasedBuf = mRecordFreeQueue.itemAt(0);
+ mRecordFreeQueue.removeAt(0);
+ mRecordFreeQueueLock.unlock();
+ LOGV("%s (%d): releasedBuf.idx = %d\n", __FUNCTION__, __LINE__,
+ releasedBuf.video.video.idx);
+ if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId,&releasedBuf))
+ LOGE("%s : Buf Done Failed",__func__);
+ }
+ mRecordFreeQueueLock.unlock();
+#if 0
+ while (!mRecordFreeQueue.isEmpty()) {
+ LOGE("%s : Waiting for Encoder to release all buffer!\n", __FUNCTION__);
+ }
+#endif
+#endif // mzhu
+ /* unregister the notify fn from the mmmm_camera_t object
+ * call stop() in parent class to stop the monitor thread */
+
+ ret = cam_ops_action(mCameraId, FALSE, MM_CAMERA_OPS_VIDEO, 0);
+ if (MM_CAMERA_OK != ret) {
+ LOGE ("%s ERROR: Video streaming Stop err=%d\n", __func__, ret);
+ }
+
+ ret = cam_config_unprepare_buf(mCameraId, MM_CAMERA_CH_VIDEO);
+ if(ret != MM_CAMERA_OK){
+ LOGE("%s ERROR: Ureg video buf \n", __func__);
+ }
+#endif
+ for(int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) {
+ if (mHalCamCtrl->mStoreMetaDataInFrame) {
+ struct encoder_media_buffer_type * packet =
+ (struct encoder_media_buffer_type *)
+ mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->data;
+ native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle));
+ mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->release(
+ mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]);
+
+ }
+#if 0
+ mHalCamCtrl->mRecordingMemory.camera_memory[cnt]->release(
+ mHalCamCtrl->mRecordingMemory.camera_memory[cnt]);
+ close(mHalCamCtrl->mRecordingMemory.fd[cnt]);
+
+#ifdef USE_ION
+ mHalCamCtrl->deallocate_ion_memory(&mHalCamCtrl->mRecordingMemory, cnt);
+#endif
+#endif
+ }
+#if 0
+memset(&mHalCamCtrl->mRecordingMemory, 0, sizeof(mHalCamCtrl->mRecordingMemory));
+ //mNumRecordFrames = 0;
+ delete[] recordframes;
+ if (mRecordBuf.video.video.buf.mp)
+ delete[] mRecordBuf.video.video.buf.mp;
+
+
+ mActive = false;
+#endif
+ LOGV("%s: END", __func__);
+
+}
+// ---------------------------------------------------------------------------
+// QCameraStream_record
+// ---------------------------------------------------------------------------
+void QCameraStream_record::release()
+{
+ status_t ret = NO_ERROR;
+ LOGV("%s: BEGIN", __func__);
+#if 0
+ if(mActive) {
+ stop();
+ }
+ if(!mInit) {
+ LOGE("%s : Record stream not initialized",__func__);
+ return;
+ }
+
+ ret= QCameraStream::deinitChannel(mCameraId, MM_CAMERA_CH_VIDEO);
+ if(ret != MM_CAMERA_OK) {
+ LOGE("%s:Deinit Video channel failed=%d\n", __func__, ret);
+ }
+ (void)cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO,
+ NULL,
+ NULL);
+ mInit = false;
+#endif
+ LOGV("%s: END", __func__);
+}
+
+status_t QCameraStream_record::processRecordFrame(void *data)
+{
+ LOGE("%s : BEGIN",__func__);
+#if 0
+ mm_camera_ch_data_buf_t* frame = (mm_camera_ch_data_buf_t*) data;
+
+ Mutex::Autolock lock(mStopCallbackLock);
+ if(!mActive) {
+ LOGE("Recording Stopped. Returning callback");
+ return NO_ERROR;
+ }
+
+ if (UNLIKELY(mDebugFps)) {
+ debugShowVideoFPS();
+ }
+
+
+ mHalCamCtrl->dumpFrameToFile(frame->video.video.frame, HAL_DUMP_FRM_VIDEO);
+ mHalCamCtrl->mCallbackLock.lock();
+ camera_data_timestamp_callback rcb = mHalCamCtrl->mDataCbTimestamp;
+ void *rdata = mHalCamCtrl->mCallbackCookie;
+ mHalCamCtrl->mCallbackLock.unlock();
+
+ nsecs_t timeStamp = nsecs_t(frame->video.video.frame->ts.tv_sec)*1000000000LL + \
+ frame->video.video.frame->ts.tv_nsec;
+
+ if(snapshot_enabled) {
+ LOGE("Live Snapshot Enabled");
+ frame->snapshot.main.frame = frame->video.video.frame;
+ frame->snapshot.main.idx = frame->video.video.idx;
+ frame->snapshot.thumbnail.frame = frame->video.video.frame;
+ frame->snapshot.thumbnail.idx = frame->video.video.idx;
+
+ dim.picture_width = mHalCamCtrl->mDimension.video_width;
+ dim.picture_height = mHalCamCtrl->mDimension.video_height;
+ dim.ui_thumbnail_width = mHalCamCtrl->mDimension.display_width;
+ dim.ui_thumbnail_height = mHalCamCtrl->mDimension.display_height;
+
+ mJpegMaxSize = mHalCamCtrl->mDimension.video_width * mHalCamCtrl->mDimension.video_width * 1.5;
+
+ LOGE("Picture w = %d , h = %d, size = %d",dim.picture_width,dim.picture_height,mJpegMaxSize);
+ if (mStreamSnap){
+ LOGE("%s:Deleting old Snapshot stream instance",__func__);
+ QCameraStream_Snapshot::deleteInstance (mStreamSnap);
+ mStreamSnap = NULL;
+ }
+
+ mStreamSnap = QCameraStream_Snapshot::createInstance(mCameraId,
+ myMode);
+
+ if (!mStreamSnap) {
+ LOGE("%s: error - can't creat snapshot stream!", __func__);
+ return BAD_VALUE;
+ }
+ mStreamSnap->setHALCameraControl(this->mHalCamCtrl);
+ mStreamSnap->takePictureLiveshot(frame,&dim,mJpegMaxSize);
+
+ snapshot_enabled = false;
+ }
+
+ LOGE("Send Video frame to services/encoder TimeStamp : %lld",timeStamp);
+ mRecordedFrames[frame->video.video.idx] = *frame;
+#if 1
+ if (mHalCamCtrl->mStoreMetaDataInFrame) {
+ mStopCallbackLock.unlock();
+ if(mActive && (rcb != NULL) && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
+ rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
+ mHalCamCtrl->mRecordingMemory.metadata_memory[frame->video.video.idx],
+ 0, mHalCamCtrl->mCallbackCookie);
+ }
+ } else {
+ //rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME, mRecordHeap->mBuffers[frame->video.video.idx], rdata);
+ mStopCallbackLock.unlock();
+ if(mActive && (rcb != NULL) && (mHalCamCtrl->mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
+ rcb(timeStamp, CAMERA_MSG_VIDEO_FRAME,
+ mHalCamCtrl->mRecordingMemory.camera_memory[frame->video.video.idx],
+ 0, mHalCamCtrl->mCallbackCookie);
+ }
+ }
+#else //Dump the Frame
+ {
+ static int frameCnt = 0;
+ if (frameCnt <= 13 ) {
+ char buf[128];
+ snprintf(buf, sizeof(buf), "/data/%d_video.yuv", frameCnt);
+ int file_fd = open(buf, O_RDWR | O_CREAT, 0777);
+ LOGE("dumping video frame %d", frameCnt);
+ if (file_fd < 0) {
+ LOGE("cannot open file\n");
+ }
+ else
+ {
+ LOGE("Dump Frame size = %d",record_frame_len);
+ write(file_fd, (const void *)(const void *)frame->video.video.frame->buffer,
+ record_frame_len);
+ }
+ close(file_fd);
+ }
+ frameCnt++;
+ }
+ if(MM_CAMERA_OK! = cam_evt_buf_done(mCameraId, frame))
+ LOGE("%s : BUF DONE FAILED",__func__);
+#endif
+#endif
+ LOGE("%s : END",__func__);
+ return NO_ERROR;
+}
+
+//Record Related Functions
+status_t QCameraStream_record::initEncodeBuffers()
+{
+ LOGE("%s : BEGIN",__func__);
+ status_t ret = NO_ERROR;
+#if 0
+ const char *pmem_region;
+ uint32_t frame_len;
+ uint8_t num_planes;
+ uint32_t planes[VIDEO_MAX_PLANES];
+ //cam_ctrl_dimension_t dim;
+ int width = 0; /* width of channel */
+ int height = 0; /* height of channel */
+
+ pmem_region = "/dev/pmem_adsp";
+
+
+ memset(&mHalCamCtrl->mRecordingMemory, 0, sizeof(mHalCamCtrl->mRecordingMemory));
+ memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
+ ret = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
+ if (MM_CAMERA_OK != ret) {
+ LOGE("%s: ERROR - can't get camera dimension!", __func__);
+ return BAD_VALUE;
+ }
+ else {
+ width = dim.video_width;
+ height = dim.video_height;
+ }
+ num_planes = 2;
+ planes[0] = dim.video_frame_offset.mp[0].len;
+ planes[1] = dim.video_frame_offset.mp[1].len;
+ frame_len = dim.video_frame_offset.frame_len;
+
+#if 0
+ if(mRecordHeap == NULL)
+ {
+#ifdef USE_ION
+ mRecordHeap = new IonPool(
+ MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
+ frame_len,
+ VIDEO_BUFFER_COUNT,
+ frame_len,
+ planes[0],
+ 0,
+ "record");
+#else
+ mRecordHeap = new PmemPool(pmem_region,
+ MemoryHeapBase::READ_ONLY | MemoryHeapBase::NO_CACHING,
+ MSM_PMEM_VIDEO,
+ frame_len,
+ VIDEO_BUFFER_COUNT,
+ frame_len,
+ planes[0],
+ 0,
+ "record");
+#endif
+ if (!mRecordHeap->initialized()) {
+ mRecordHeap.clear();
+ mRecordHeap = NULL;
+ LOGE("%s: ERROR : could not initialize record heap.",__func__);
+ return BAD_VALUE;
+ }
+ } else {
+ /*if(mHFRMode == true) {
+ LOGI("%s: register record buffers with camera driver", __FUNCTION__);
+ register_record_buffers(true);
+ mHFRMode = false;
+ }*/
+ }
+ LOGE("PMEM Buffer Allocation Successfull");
+#endif
+
+#if 0
+ memset(&mRecordBuf, 0, sizeof(mRecordBuf));
+ /* allocate memory for mplanar frame struct. */
+ mRecordBuf.video.video.buf.mp = new mm_camera_mp_buf_t[VIDEO_BUFFER_COUNT *
+ sizeof(mm_camera_mp_buf_t)];
+ if (!mRecordBuf.video.video.buf.mp) {
+ LOGE("%s Error allocating memory for mplanar struct ", __func__);
+ mRecordHeap.clear();
+ mRecordHeap = NULL;
+ return BAD_VALUE;
+ }
+ memset(mRecordBuf.video.video.buf.mp, 0,
+ VIDEO_BUFFER_COUNT * sizeof(mm_camera_mp_buf_t));
+ mRecordBuf.ch_type = MM_CAMERA_CH_VIDEO;
+ mRecordBuf.video.video.num = VIDEO_BUFFER_COUNT;//kRecordBufferCount;
+ recordframes = new msm_frame[VIDEO_BUFFER_COUNT];
+ if(recordframes != NULL) {
+ memset(recordframes,0,sizeof(struct msm_frame) * VIDEO_BUFFER_COUNT);
+ for (int cnt = 0; cnt < VIDEO_BUFFER_COUNT; cnt++) {
+ recordframes[cnt].fd = mRecordHeap->mHeap->getHeapID();
+ recordframes[cnt].buffer =
+ (uint32_t)mRecordHeap->mHeap->base() + mRecordHeap->mAlignedBufferSize * cnt;
+ recordframes[cnt].y_off = 0;
+ recordframes[cnt].cbcr_off = planes[0];
+ recordframes[cnt].path = OUTPUT_TYPE_V;
+ //record_buffers_tracking_flag[cnt] = false;
+ record_offset[cnt] = mRecordHeap->mAlignedBufferSize * cnt;
+ LOGE ("initRecord : record heap , video buffers buffer=%lu fd=%d offset = %d \n",
+ (unsigned long)recordframes[cnt].buffer, recordframes[cnt].fd, record_offset[cnt]);
+ mRecordBuf.video.video.buf.mp[cnt].frame = recordframes[cnt];
+ mRecordBuf.video.video.buf.mp[cnt].frame_offset = record_offset[cnt];
+ mRecordBuf.video.video.buf.mp[cnt].num_planes = num_planes;
+ /* Plane 0 needs to be set seperately. Set other planes
+ * in a loop. */
+ mRecordBuf.video.video.buf.mp[cnt].planes[0].reserved[0] =
+ mRecordBuf.video.video.buf.mp[cnt].frame_offset;
+ mRecordBuf.video.video.buf.mp[cnt].planes[0].length = planes[0];
+ mRecordBuf.video.video.buf.mp[cnt].planes[0].m.userptr =
+ recordframes[cnt].fd;
+ for (int j = 1; j < num_planes; j++) {
+ mRecordBuf.video.video.buf.mp[cnt].planes[j].length = planes[j];
+ mRecordBuf.video.video.buf.mp[cnt].planes[j].m.userptr =
+ recordframes[cnt].fd;
+ mRecordBuf.video.video.buf.mp[cnt].planes[j].reserved[0] =
+ mRecordBuf.video.video.buf.mp[cnt].planes[j-1].reserved[0] +
+ mRecordBuf.video.video.buf.mp[cnt].planes[j-1].length;
+ }
+ }
+ LOGE("Record buf type =%d, offset[1] =%d, buffer[1] =%lx", mRecordBuf.ch_type, record_offset[1], recordframes[1].buffer);
+ LOGE("%s : END",__func__);
+ } else {
+ ret = NO_MEMORY;
+ }
+ return ret;
+#endif
+
+ recordframes = new msm_frame[VIDEO_BUFFER_COUNT];
+ memset(recordframes,0,sizeof(struct msm_frame) * VIDEO_BUFFER_COUNT);
+
+ mRecordBuf.video.video.buf.mp = new mm_camera_mp_buf_t[VIDEO_BUFFER_COUNT *
+ sizeof(mm_camera_mp_buf_t)];
+ if (!mRecordBuf.video.video.buf.mp) {
+ LOGE("%s Error allocating memory for mplanar struct ", __func__);
+ return BAD_VALUE;
+ }
+ memset(mRecordBuf.video.video.buf.mp, 0,
+ VIDEO_BUFFER_COUNT * sizeof(mm_camera_mp_buf_t));
+
+ memset(&mHalCamCtrl->mRecordingMemory, 0, sizeof(mHalCamCtrl->mRecordingMemory));
+ mHalCamCtrl->mRecordingMemory.buffer_count = VIDEO_BUFFER_COUNT;
+
+ mHalCamCtrl->mRecordingMemory.size = frame_len;
+ mHalCamCtrl->mRecordingMemory.cbcr_offset = planes[0];
+#endif
+ for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) {
+#if 0
+#ifdef USE_ION
+ if(mHalCamCtrl->allocate_ion_memory(&mHalCamCtrl->mRecordingMemory, cnt, ION_CP_MM_HEAP_ID) < 0) {
+ LOGE("%s ION alloc failed\n", __func__);
+ return UNKNOWN_ERROR;
+ }
+#else
+ mHalCamCtrl->mRecordingMemory.fd[cnt] = open("/dev/pmem_adsp", O_RDWR|O_SYNC);
+ if(mHalCamCtrl->mRecordingMemory.fd[cnt] <= 0) {
+ LOGE("%s: no pmem for frame %d", __func__, cnt);
+ return UNKNOWN_ERROR;
+ }
+#endif
+ mHalCamCtrl->mRecordingMemory.camera_memory[cnt] =
+ mHalCamCtrl->mGetMemory(mHalCamCtrl->mRecordingMemory.fd[cnt],
+ mHalCamCtrl->mRecordingMemory.size, 1, (void *)this);
+#endif
+ if (mHalCamCtrl->mStoreMetaDataInFrame) {
+ mHalCamCtrl->mRecordingMemory.metadata_memory[cnt] =
+ mHalCamCtrl->mGetMemory(-1,
+ sizeof(struct encoder_media_buffer_type), 1, (void *)this);
+ struct encoder_media_buffer_type * packet =
+ (struct encoder_media_buffer_type *)
+ mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->data;
+ packet->meta_handle = native_handle_create(1, 2); //1 fd, 1 offset and 1 size
+ packet->buffer_type = kMetadataBufferTypeCameraSource;
+ native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
+ nh->data[0] = mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd;
+ nh->data[1] = 0;
+ nh->data[2] = mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size;
+ nh->data[3] = (uint32_t)mHalCamCtrl->mPreviewMemory.camera_memory[cnt]->data;
+ }
+ #if 0
+ recordframes[cnt].fd = mHalCamCtrl->mRecordingMemory.fd[cnt];
+ recordframes[cnt].buffer = (uint32_t)mHalCamCtrl->mRecordingMemory.camera_memory[cnt]->data;
+ recordframes[cnt].y_off = 0;
+ recordframes[cnt].cbcr_off = mHalCamCtrl->mRecordingMemory.cbcr_offset;
+ recordframes[cnt].path = OUTPUT_TYPE_V;
+ //record_offset[cnt] = mRecordHeap->mAlignedBufferSize * cnt;
+
+ //record_buffers_tracking_flag[cnt] = false;
+ //record_offset[cnt] = 0;
+ LOGE ("initRecord : record heap , video buffers buffer=%lu fd=%d y_off=%d cbcr_off=%d\n",
+ (unsigned long)recordframes[cnt].buffer, recordframes[cnt].fd, recordframes[cnt].y_off,
+ recordframes[cnt].cbcr_off);
+ //mNumRecordFrames++;
+
+ mRecordBuf.video.video.buf.mp[cnt].frame = recordframes[cnt];
+ mRecordBuf.video.video.buf.mp[cnt].frame_offset = 0;
+ mRecordBuf.video.video.buf.mp[cnt].num_planes = num_planes;
+ /* Plane 0 needs to be set seperately. Set other planes
+ * in a loop. */
+ mRecordBuf.video.video.buf.mp[cnt].planes[0].reserved[0] =
+ mRecordBuf.video.video.buf.mp[cnt].frame_offset;
+ mRecordBuf.video.video.buf.mp[cnt].planes[0].length = planes[0];
+ mRecordBuf.video.video.buf.mp[cnt].planes[0].m.userptr =
+ recordframes[cnt].fd;
+ for (int j = 1; j < num_planes; j++) {
+ mRecordBuf.video.video.buf.mp[cnt].planes[j].length = planes[j];
+ mRecordBuf.video.video.buf.mp[cnt].planes[j].m.userptr =
+ recordframes[cnt].fd;
+ mRecordBuf.video.video.buf.mp[cnt].planes[j].reserved[0] =
+ mRecordBuf.video.video.buf.mp[cnt].planes[j-1].reserved[0] +
+ mRecordBuf.video.video.buf.mp[cnt].planes[j-1].length;
+
+ }
+#endif
+ }
+#if 0
+ //memset(&mRecordBuf, 0, sizeof(mRecordBuf));
+ mRecordBuf.ch_type = MM_CAMERA_CH_VIDEO;
+ mRecordBuf.video.video.num = mHalCamCtrl->mRecordingMemory.buffer_count;//kRecordBufferCount;
+ //mRecordBuf.video.video.frame_offset = &record_offset[0];
+ //mRecordBuf.video.video.frame = &recordframes[0];
+#endif
+ LOGE("%s : END",__func__);
+ return NO_ERROR;
+}
+
+void QCameraStream_record::releaseRecordingFrame(const void *opaque)
+{
+ LOGE("%s : BEGIN, opaque = 0x%p",__func__, opaque);
+#if 0
+ if(!mActive)
+ {
+ LOGE("%s : Recording already stopped!!! Leak???",__func__);
+ return;
+ }
+ for(int cnt = 0; cnt < mHalCamCtrl->mRecordingMemory.buffer_count; cnt++) {
+ if (mHalCamCtrl->mStoreMetaDataInFrame) {
+ if(mHalCamCtrl->mRecordingMemory.metadata_memory[cnt] &&
+ mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->data == opaque) {
+ /* found the match */
+ if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mRecordedFrames[cnt]))
+ LOGE("%s : Buf Done Failed",__func__);
+ LOGE("%s : END",__func__);
+ return;
+ }
+ } else {
+ if(mHalCamCtrl->mRecordingMemory.camera_memory[cnt] &&
+ mHalCamCtrl->mRecordingMemory.camera_memory[cnt]->data == opaque) {
+ /* found the match */
+ if(MM_CAMERA_OK != cam_evt_buf_done(mCameraId, &mRecordedFrames[cnt]))
+ LOGE("%s : Buf Done Failed",__func__);
+ LOGE("%s : END",__func__);
+ return;
+ }
+ }
+ }
+#endif
+ LOGE("%s: cannot find the matched frame with opaue = 0x%p", __func__, opaque);
+}
+
+void QCameraStream_record::debugShowVideoFPS() const
+{
+#if 0
+ static int mFrameCount;
+ static int mLastFrameCount = 0;
+ static nsecs_t mLastFpsTime = 0;
+ static float mFps = 0;
+ mFrameCount++;
+ nsecs_t now = systemTime();
+ nsecs_t diff = now - mLastFpsTime;
+ if (diff > ms2ns(250)) {
+ mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
+ LOGI("Video Frames Per Second: %.4f", mFps);
+ mLastFpsTime = now;
+ mLastFrameCount = mFrameCount;
+ }
+#endif
+}
+
+#if 0
+sp<IMemoryHeap> QCameraStream_record::getHeap() const
+{
+ return mRecordHeap != NULL ? mRecordHeap->mHeap : NULL;
+}
+status_t QCameraStream_record::takeLiveSnapshot()
+{
+ //snapshotframes = new msm_frame[1];
+ //memset(snapshotframes,0,sizeof(struct msm_frame));
+ //mJpegMaxSize = dim.video_width * dim.video_height * 1.5;
+ LOGE("%s: BEGIN", __func__);
+ mHalCamCtrl->snapshot_enabled = true;
+ LOGE("%s: END", __func__);
+ return true;
+}
+#endif
+
+status_t QCameraStream_record::takeLiveSnapshot(){
+ return true;
+}
+
+}//namespace android
diff --git a/QCameraHWI_Still.cpp b/QCameraHWI_Still.cpp
index b43e90f..84adb88 100755
--- a/QCameraHWI_Still.cpp
+++ b/QCameraHWI_Still.cpp
@@ -1436,7 +1436,10 @@
set_callbacks(snapshot_jpeg_fragment_cb, snapshot_jpeg_cb, this,
mHalCamCtrl->mJpegMemory.camera_memory[0]->data, &mJpegOffset);
omxJpegStart();
- mm_jpeg_encoder_setMainImageQuality(mHalCamCtrl->getJpegQuality());
+ if (mHalCamCtrl->getJpegQuality())
+ mm_jpeg_encoder_setMainImageQuality(mHalCamCtrl->getJpegQuality());
+ else
+ mm_jpeg_encoder_setMainImageQuality(85);
LOGD("%s: Dimension to encode: main: %dx%d thumbnail: %dx%d", __func__,
dimension.orig_picture_dx, dimension.orig_picture_dy,
diff --git a/QCameraStream.cpp b/QCameraStream.cpp
index 5d744c6..48c2363 100755
--- a/QCameraStream.cpp
+++ b/QCameraStream.cpp
@@ -1,5 +1,5 @@
/*
-** Copyright (c) 2011 Code Aurora Forum. All rights reserved.
+** Copyright (c) 2011-2012 Code Aurora Forum. All rights reserved.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -262,7 +262,7 @@
int height = 0; /* height of channel */
cam_ctrl_dimension_t dim;
mm_camera_ch_image_fmt_parm_t fmt;
-
+ int preview_format;
LOGE("%s: E",__func__);
memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
@@ -272,11 +272,14 @@
LOGE("%s: X", __func__);
return BAD_VALUE;
}
-
+ char mDeviceName[PROPERTY_VALUE_MAX];
+ property_get("ro.product.device",mDeviceName," ");
memset(&fmt, 0, sizeof(mm_camera_ch_image_fmt_parm_t));
if(MM_CAMERA_CH_PREVIEW_MASK & ch_type_mask){
fmt.ch_type = MM_CAMERA_CH_PREVIEW;
- fmt.def.fmt = CAMERA_YUV_420_NV12; //dim.prev_format;
+ ret = cam_config_get_parm(mCameraId,
+ MM_CAMERA_PARM_PREVIEW_FORMAT, &preview_format);
+ fmt.def.fmt = (cam_format_t)preview_format;
fmt.def.dim.width = dim.display_width;
fmt.def.dim.height = dim.display_height;
}else if(MM_CAMERA_CH_VIDEO_MASK & ch_type_mask){
diff --git a/mm_camera.c b/mm_camera.c
index dcc2a9b..6fbf486 100755
--- a/mm_camera.c
+++ b/mm_camera.c
@@ -484,6 +484,9 @@
dim->width, dim->height);
}
break;
+ case MM_CAMERA_PARM_PREVIEW_FORMAT:
+ *((int *)parm->p_value) = my_obj->properties.preview_format;
+ break;
case MM_CAMERA_PARM_MAX_PREVIEW_SIZE: {
mm_camera_dimension_t *dim =
(mm_camera_dimension_t *)parm->p_value;