Camera3: Enable preview
- initial_reg_flag is used to indicate whether to queue
buffers to the hardware before streamon. Remove code
in mm_stream_qbuf where VIDIOC_REQBUFS is skipped if
any of initial_reg_flag is 0.
- Apply change I5f8f5e2b2c86dfae3cae2b76886dd96eb1d261cc:
"QCamera2: Trigger buffer cache invalidate just before queuing"
- Use PRIV_FLAGS_HW_TEXTURE private gralloc usage flag for
preview frame.
- Improve member variables initialization and cleanup
for QCamera3HWI class.
- Remove redundant functions in QCamera3HWI.
- Add cleanInvalidateBuf function pointer to mMemVtbl.
Change-Id: I416bd169eb0d98ed268c41f128636ed451c6de23
diff --git a/camera/QCamera2/HAL3/QCamera3Channel.cpp b/camera/QCamera2/HAL3/QCamera3Channel.cpp
index 79b8fe1..358ea69 100644
--- a/camera/QCamera2/HAL3/QCamera3Channel.cpp
+++ b/camera/QCamera2/HAL3/QCamera3Channel.cpp
@@ -493,7 +493,7 @@
if (priv_handle->flags & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER) {
streamType = CAM_STREAM_TYPE_VIDEO;
streamFormat = CAM_FORMAT_YUV_420_NV12;
- } else if (priv_handle->flags & private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY) {
+ } else if (priv_handle->flags & private_handle_t::PRIV_FLAGS_HW_TEXTURE) {
streamType = CAM_STREAM_TYPE_PREVIEW;
streamFormat = CAM_FORMAT_YUV_420_NV21;
} else {
@@ -644,7 +644,7 @@
return rc;
}
- streamDim.width = sizeof(parm_buffer_t),
+ streamDim.width = sizeof(metadata_buffer_t),
streamDim.height = 1;
rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_METADATA, CAM_FORMAT_MAX,
streamDim, MIN_STREAMING_BUFFER_NUM);
@@ -695,9 +695,9 @@
QCamera3Memory* QCamera3MetadataChannel::getStreamBufs(uint32_t len)
{
int rc;
- if (len != sizeof(parm_buffer_t)) {
+ if (len != sizeof(metadata_buffer_t)) {
ALOGE("%s: size doesn't match %d vs %d", __func__,
- len, sizeof(parm_buffer_t));
+ len, sizeof(metadata_buffer_t));
return NULL;
}
mMemory = new QCamera3HeapMemory();
@@ -712,7 +712,7 @@
mMemory = NULL;
return NULL;
}
- memset(mMemory->getPtr(0), 0, sizeof(parm_buffer_t));
+ memset(mMemory->getPtr(0), 0, sizeof(metadata_buffer_t));
return mMemory;
}
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.cpp b/camera/QCamera2/HAL3/QCamera3HWI.cpp
index 142b483..6bbd748 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/camera/QCamera2/HAL3/QCamera3HWI.cpp
@@ -147,6 +147,11 @@
mCameraHandle(NULL),
mCameraOpened(false),
mCallbackOps(NULL),
+ mInputStream(NULL),
+ mMetadataChannel(NULL),
+ mFirstRequest(false),
+ mParamHeap(NULL),
+ mParameters(NULL),
mJpegSettings(NULL)
{
mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
@@ -161,6 +166,10 @@
mPendingRequest = 0;
pthread_mutex_init(&mMutex, NULL);
+ pthread_mutex_init(&mCaptureResultLock, NULL);
+
+ for (size_t i = 0; i < CAMERA3_TEMPLATE_COUNT; i++)
+ mDefaultMetadata[i] = NULL;
}
/*===========================================================================
@@ -178,12 +187,18 @@
free(mJpegSettings);
mJpegSettings = NULL;
}
+ deinitParameters();
closeCamera();
+ for (size_t i = 0; i < CAMERA3_TEMPLATE_COUNT; i++)
+ if (mDefaultMetadata[i])
+ free_camera_metadata(mDefaultMetadata[i]);
+
pthread_mutex_destroy(&mRequestLock);
pthread_cond_destroy(&mRequestCond);
pthread_mutex_destroy(&mMutex);
+ pthread_mutex_destroy(&mCaptureResultLock);
}
/*===========================================================================
@@ -266,41 +281,6 @@
}
/*===========================================================================
- * FUNCTION : sendCaptureResult
- *
- * DESCRIPTION: send completed capture result metadata buffer along with possibly
- * completed output stream buffers to the framework
- *
- * PARAMETERS :
- *
- * RETURN :
- *==========================================================================*/
-void QCamera3HardwareInterface::sendCaptureResult(const struct camera3_callback_ops *,
- const camera3_capture_result_t *result)
-{
- //TODO - Implement
-}
-
-/*===========================================================================
- * FUNCTION : notify
- *
- * DESCRIPTION: Asynchronous notification callback to framework
- *
- * PARAMETERS :
- *
- * RETURN :
- *
- *
- *==========================================================================*/
-
-void QCamera3HardwareInterface::notify(const struct camera3_callback_ops *,
- const camera3_notify_msg_t *msg)
-{
- //TODO - Implement
-}
-
-
-/*===========================================================================
* FUNCTION : initialize
*
* DESCRIPTION: Initialize frameworks callback functions
@@ -318,6 +298,11 @@
pthread_mutex_lock(&mMutex);
+ rc = initParameters();
+ if (rc < 0) {
+ ALOGE("%s: initParamters failed %d", __func__, rc);
+ goto err1;
+ }
//Create metadata channel and initialize it
mMetadataChannel = new QCamera3MetadataChannel(mCameraHandle->camera_handle,
mCameraHandle->ops, captureResultCb,
@@ -325,47 +310,24 @@
if (mMetadataChannel == NULL) {
ALOGE("%s: failed to allocate metadata channel", __func__);
rc = -ENOMEM;
- goto err1;
+ goto err2;
}
rc = mMetadataChannel->initialize();
if (rc < 0) {
ALOGE("%s: metadata channel initialization failed", __func__);
- goto err2;
- }
-
- /* Initialize parameter heap and structure */
- mParamHeap = new QCamera3HeapMemory();
- if (mParamHeap == NULL) {
- ALOGE("%s: creation of mParamHeap failed", __func__);
- goto err2;
- }
- rc = mParamHeap->allocate(1, sizeof(parm_buffer_t), false);
- if (rc < 0) {
- ALOGE("%s: allocation of mParamHeap failed", __func__);
goto err3;
}
- rc = mCameraHandle->ops->map_buf(mCameraHandle->camera_handle,
- CAM_MAPPING_BUF_TYPE_PARM_BUF,
- mParamHeap->getFd(0), sizeof(parm_buffer_t));
- if (rc < 0) {
- ALOGE("%s: map_buf failed for mParamHeap", __func__);
- goto err4;
- }
- mParameters = (parm_buffer_t *)DATA_PTR(mParamHeap, 0);
mCallbackOps = callback_ops;
pthread_mutex_unlock(&mMutex);
return 0;
-err4:
- mParamHeap->deallocate();
err3:
- delete mParamHeap;
- mParamHeap = NULL;
-err2:
delete mMetadataChannel;
mMetadataChannel = NULL;
+err2:
+ deinitParameters();
err1:
pthread_mutex_unlock(&mMutex);
return rc;
@@ -387,7 +349,7 @@
camera3_stream_configuration_t *streamList)
{
pthread_mutex_lock(&mMutex);
- int rc;
+ int rc = 0;
// Sanity check stream_list
if (streamList == NULL) {
@@ -426,7 +388,7 @@
/* TODO: Clean up no longer used streams, and maintain others if this
* is not the 1st time configureStreams is called */
- mMetadataChannel->stop();
+ //mMetadataChannel->stop();
/* Allocate channel objects for the requested streams */
for (size_t i = 0; i < streamList->num_streams; i++) {
@@ -502,11 +464,13 @@
}
}
- // Cannot reuse settings across configure call
+ //settings/parameters don't carry over for new configureStreams
memset(mParameters, 0, sizeof(parm_buffer_t));
+ mFirstRequest = true;
+
end:
pthread_mutex_unlock(&mMutex);
- return 0;
+ return rc;
}
/*===========================================================================
@@ -673,12 +637,12 @@
uint32_t frameNumber = request->frame_number;
rc = setFrameParameters(request->frame_number, request->settings);
-
if (rc < 0) {
ALOGE("%s: fail to set frame parameters", __func__);
pthread_mutex_unlock(&mMutex);
return rc;
}
+ mFirstRequest = false;
// Acquire all request buffers first
for (size_t i = 0; i < request->num_output_buffers; i++) {
@@ -785,11 +749,13 @@
/*===========================================================================
* FUNCTION : captureResultCb
*
- * DESCRIPTION: Callback handler for all capture result (streams, as well as metadata)
+ * DESCRIPTION: Callback handler for all capture result
+ * (streams, as well as metadata)
*
* PARAMETERS :
* @metadata : metadata information
- * @buffer : actual gralloc buffer to be returned to frameworks. NULL if metadata.
+ * @buffer : actual gralloc buffer to be returned to frameworks.
+ * NULL if metadata.
*
* RETURN : NONE
*==========================================================================*/
@@ -799,7 +765,6 @@
pthread_mutex_lock(&mCaptureResultLock);
camera3_capture_result_t result;
-
if (metadata) {
// Signal to unblock processCaptureRequest
pthread_mutex_lock(&mRequestLock);
@@ -807,25 +772,56 @@
pthread_cond_signal(&mRequestCond);
pthread_mutex_unlock(&mRequestLock);
- uint32_t *frame_number = (uint32_t *)POINTER_OF(CAM_INTF_META_FRAME_NUMBER, metadata);
+ int32_t frame_number_valid = *(int32_t *)
+ POINTER_OF(CAM_INTF_META_FRAME_NUMBER_VALID, metadata);
+ ALOGE("%s: frame_number_valid = %d", __func__, frame_number_valid);
+ if (!frame_number_valid) {
+ ALOGI("%s: Not a valid frame number, used as SOF only", __func__);
+ goto done;
+ }
+ uint32_t frame_number = *(uint32_t *)
+ POINTER_OF(CAM_INTF_META_FRAME_NUMBER, metadata);
+#if 1
+ nsecs_t capture_time = 1000000 * frame_number * 33;
+#else
+ nsecs_t capture_time = *(int64_t *)
+ POINTER_OF(CAM_INTF_META_SENSOR_EXPOSURE_TIME, metadata);
+#endif
+ ALOGE("%s: notify frame_number = %d, capture_time = %lld", __func__,
+ frame_number, capture_time);
+
+ /* Send shutter notify */
+ camera3_notify_msg_t notify_msg;
+ notify_msg.type = CAMERA3_MSG_SHUTTER;
+ notify_msg.message.shutter.frame_number = frame_number;
+ notify_msg.message.shutter.timestamp = capture_time;
+ mCallbackOps->notify(mCallbackOps, ¬ify_msg);
+
+ /* send capture result with metadata only */
result.result = translateCbMetadataToResultMetadata(metadata);
- if (!result.result) {
- result.frame_number = *frame_number;
+ if (result.result) {
+ result.frame_number = frame_number;
result.num_output_buffers = 0;
result.output_buffers = NULL;
mCallbackOps->process_capture_result(mCallbackOps, &result);
+ ALOGE("%s: metadata frame_number = %d, capture_time = %ld",
+ __func__, frame_number, capture_time);
free_camera_metadata((camera_metadata_t*)result.result);
+ } else {
+ ALOGE("%s: metadata is NULL", __func__);
}
} else {
result.result = NULL;
result.frame_number = frame_number;
result.num_output_buffers = 1;
result.output_buffers = buffer;
+ ALOGE("%s: result frame_number = %d", __func__, frame_number);
mCallbackOps->process_capture_result(mCallbackOps, &result);
}
+done:
pthread_mutex_unlock(&mCaptureResultLock);
return;
}
@@ -848,10 +844,16 @@
CameraMetadata camMetadata;
camera_metadata_t* resultMetadata;
- uint32_t *frame_number =
- (uint32_t *)POINTER_OF(CAM_INTF_META_FRAME_NUMBER, metadata);
- nsecs_t captureTime = 1000000 * (*frame_number) * 33;
+#if 1
+ uint32_t frame_number = *(uint32_t *)
+ POINTER_OF(CAM_INTF_META_FRAME_NUMBER, metadata);
+ nsecs_t captureTime = 1000000 * frame_number * 33;
camMetadata.update(ANDROID_SENSOR_TIMESTAMP, &captureTime, 1);
+#else
+ nsecs_t *captureTime = (nsecs_t *)POINTER_OF(CAM_INTF_META_SENSOR_TIMESTAMP, metadata);
+ camMetadata.update(ANDROID_SENSOR_TIMESTAMP, captureTime, 1);
+#endif
+
/*CAM_INTF_META_HISTOGRAM - TODO*/
/*cam_hist_stats_t *histogram =
@@ -1047,7 +1049,7 @@
CAM_MAX_MAP_WIDTH*CAM_MAX_MAP_HEIGHT);
resultMetadata = camMetadata.release();
- return NULL;
+ return resultMetadata;
}
/*===========================================================================
@@ -1211,12 +1213,31 @@
}
mParameters = (parm_buffer_t*) DATA_PTR(mParamHeap,0);
- memset(mParameters, 0, sizeof(parm_buffer_t));
- mParameters->first_flagged_entry = CAM_INTF_PARM_MAX;
return rc;
}
/*===========================================================================
+ * FUNCTION : deinitParameters
+ *
+ * DESCRIPTION: de-initialize camera parameters
+ *
+ * PARAMETERS :
+ *
+ * RETURN : NONE
+ *==========================================================================*/
+void QCamera3HardwareInterface::deinitParameters()
+{
+ mCameraHandle->ops->unmap_buf(mCameraHandle->camera_handle,
+ CAM_MAPPING_BUF_TYPE_PARM_BUF);
+
+ mParamHeap->deallocate();
+ delete mParamHeap;
+ mParamHeap = NULL;
+
+ mParameters = NULL;
+}
+
+/*===========================================================================
* FUNCTION : initStaticMetadata
*
* DESCRIPTION: initialize the static metadata
@@ -2018,10 +2039,13 @@
{
/*translate from camera_metadata_t type to parm_type_t*/
int rc = 0;
- if (settings == NULL && mParameters == NULL) {
+ if (settings == NULL && mFirstRequest) {
/*settings cannot be null for the first request*/
return BAD_VALUE;
}
+
+ mParameters->first_flagged_entry = CAM_INTF_PARM_MAX;
+
/*we need to update the frame number in the parameters*/
rc = AddSetParmEntryToBatch(mParameters, CAM_INTF_META_FRAME_NUMBER,
sizeof(frame_id), &frame_id);
@@ -2030,9 +2054,10 @@
return BAD_VALUE;
}
if(settings != NULL){
- rc = translateMetadataToParameters(settings);
+ //rc = translateMetadataToParameters(settings);
}
/*set the parameters to backend*/
+ ALOGE("%s: %d", __func__, __LINE__);
mCameraHandle->ops->set_parms(mCameraHandle->camera_handle, mParameters);
return rc;
}
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.h b/camera/QCamera2/HAL3/QCamera3HWI.h
index 8e33554..c0b3c68 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.h
+++ b/camera/QCamera2/HAL3/QCamera3HWI.h
@@ -96,11 +96,6 @@
camera3_stream_buffer_t *buffer, uint32_t frame_number,
void *userdata);
- void sendCaptureResult(const struct camera3_callback_ops *,
- const camera3_capture_result_t *result);
- void notify(const struct camera3_callback_ops *,
- const camera3_notify_msg_t *msg);
-
int initialize(const camera3_callback_ops_t *callback_ops);
int configureStreams(camera3_stream_configuration_t *stream_list);
int registerStreamBuffers(const camera3_stream_buffer_set_t *buffer_set);
@@ -113,6 +108,7 @@
camera_metadata_t* translateCbMetadataToResultMetadata(metadata_buffer_t *metadata);
int getJpegSettings(const camera_metadata_t *settings);
int initParameters();
+ void deinitParameters();
void captureResultCb(metadata_buffer_t *metadata,
camera3_stream_buffer_t *buffer, uint32_t frame_number);
@@ -157,6 +153,8 @@
camera3_stream_t *mInputStream;
QCamera3MetadataChannel *mMetadataChannel;
+ //First request yet to be processed after configureStreams
+ bool mFirstRequest;
QCamera3HeapMemory *mParamHeap;
parm_buffer_t* mParameters;
diff --git a/camera/QCamera2/HAL3/QCamera3Mem.cpp b/camera/QCamera2/HAL3/QCamera3Mem.cpp
index 75019d1..a50893d 100644
--- a/camera/QCamera2/HAL3/QCamera3Mem.cpp
+++ b/camera/QCamera2/HAL3/QCamera3Mem.cpp
@@ -97,6 +97,7 @@
int QCamera3Memory::cacheOpsInternal(int index, unsigned int cmd, void *vaddr)
{
struct ion_flush_data cache_inv_data;
+ struct ion_custom_data custom_data;
int ret = OK;
if (index >= mBufferCount) {
@@ -105,16 +106,19 @@
}
memset(&cache_inv_data, 0, sizeof(cache_inv_data));
+ memset(&custom_data, 0, sizeof(custom_data));
cache_inv_data.vaddr = vaddr;
cache_inv_data.fd = mMemInfo[index].fd;
cache_inv_data.handle = mMemInfo[index].handle;
cache_inv_data.length = mMemInfo[index].size;
+ custom_data.cmd = cmd;
+ custom_data.arg = (unsigned long)&cache_inv_data;
- ALOGD("%s: addr = %p, fd = %d, handle = %p length = %d, ION Fd = %d",
+ ALOGV("%s: addr = %p, fd = %d, handle = %p length = %d, ION Fd = %d",
__func__, cache_inv_data.vaddr, cache_inv_data.fd,
cache_inv_data.handle, cache_inv_data.length,
mMemInfo[index].main_ion_fd);
- ret = ioctl(mMemInfo[index].main_ion_fd, cmd, &cache_inv_data);
+ ret = ioctl(mMemInfo[index].main_ion_fd, ION_IOC_CUSTOM, &custom_data);
if (ret < 0)
ALOGE("%s: Cache Invalidate failed: %s\n", __func__, strerror(errno));
diff --git a/camera/QCamera2/HAL3/QCamera3Stream.cpp b/camera/QCamera2/HAL3/QCamera3Stream.cpp
index d750278..862e0e6 100644
--- a/camera/QCamera2/HAL3/QCamera3Stream.cpp
+++ b/camera/QCamera2/HAL3/QCamera3Stream.cpp
@@ -99,6 +99,52 @@
}
/*===========================================================================
+ * FUNCTION : invalidate_buf
+ *
+ * DESCRIPTION: static function entry to invalidate a specific stream buffer
+ *
+ * PARAMETERS :
+ * @index : index of the stream buffer to invalidate
+ * @user_data : user data ptr of ops_tbl
+ *
+ * RETURN : int32_t type of status
+ * NO_ERROR -- success
+ * none-zero failure code
+ *==========================================================================*/
+int32_t QCamera3Stream::invalidate_buf(int index, void *user_data)
+{
+ QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
+ if (!stream) {
+ ALOGE("invalid stream pointer");
+ return NO_MEMORY;
+ }
+ return stream->invalidateBuf(index);
+}
+
+/*===========================================================================
+ * FUNCTION : clean_invalidate_buf
+ *
+ * DESCRIPTION: static function entry to clean and invalidate a specific stream buffer
+ *
+ * PARAMETERS :
+ * @index : index of the stream buffer to invalidate
+ * @user_data : user data ptr of ops_tbl
+ *
+ * RETURN : int32_t type of status
+ * NO_ERROR -- success
+ * none-zero failure code
+ *==========================================================================*/
+int32_t QCamera3Stream::clean_invalidate_buf(int index, void *user_data)
+{
+ QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
+ if (!stream) {
+ ALOGE("invalid stream pointer");
+ return NO_MEMORY;
+ }
+ return stream->cleanInvalidateBuf(index);
+}
+
+/*===========================================================================
* FUNCTION : QCamera3Stream
*
* DESCRIPTION: constructor of QCamera3Stream
@@ -132,6 +178,8 @@
mMemVtbl.user_data = this;
mMemVtbl.get_bufs = get_bufs;
mMemVtbl.put_bufs = put_bufs;
+ mMemVtbl.invalidate_buf = invalidate_buf;
+ mMemVtbl.clean_invalidate_buf = clean_invalidate_buf;
memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t));
}
@@ -438,9 +486,6 @@
if (rc < 0)
return FAILED_TRANSACTION;
- if ( !isTypeOf(CAM_STREAM_TYPE_METADATA) ) {
- mStreamBufs->invalidateCache(index);
- }
return rc;
}
@@ -568,6 +613,40 @@
}
/*===========================================================================
+ * FUNCTION : invalidateBuf
+ *
+ * DESCRIPTION: invalidate a specific stream buffer
+ *
+ * PARAMETERS :
+ * @index : index of the buffer to invalidate
+ *
+ * RETURN : int32_t type of status
+ * NO_ERROR -- success
+ * none-zero failure code
+ *==========================================================================*/
+int32_t QCamera3Stream::invalidateBuf(int index)
+{
+ return mStreamBufs->invalidateCache(index);
+}
+
+/*===========================================================================
+ * FUNCTION : cleanInvalidateBuf
+ *
+ * DESCRIPTION: clean and invalidate a specific stream buffer
+ *
+ * PARAMETERS :
+ * @index : index of the buffer to invalidate
+ *
+ * RETURN : int32_t type of status
+ * NO_ERROR -- success
+ * none-zero failure code
+ *==========================================================================*/
+int32_t QCamera3Stream::cleanInvalidateBuf(int index)
+{
+ return mStreamBufs->cleanInvalidateCache(index);
+}
+
+/*===========================================================================
* FUNCTION : isTypeOf
*
* DESCRIPTION: helper function to determine if the stream is of the queried type
diff --git a/camera/QCamera2/HAL3/QCamera3Stream.h b/camera/QCamera2/HAL3/QCamera3Stream.h
index f3cf565..e98883c 100644
--- a/camera/QCamera2/HAL3/QCamera3Stream.h
+++ b/camera/QCamera2/HAL3/QCamera3Stream.h
@@ -113,6 +113,8 @@
static int32_t put_bufs(
mm_camera_map_unmap_ops_tbl_t *ops_tbl,
void *user_data);
+ static int32_t invalidate_buf(int index, void *user_data);
+ static int32_t clean_invalidate_buf(int index, void *user_data);
int32_t getBufs(cam_frame_len_offset_t *offset,
uint8_t *num_bufs,
@@ -120,6 +122,8 @@
mm_camera_buf_def_t **bufs,
mm_camera_map_unmap_ops_tbl_t *ops_tbl);
int32_t putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl);
+ int32_t invalidateBuf(int index);
+ int32_t cleanInvalidateBuf(int index);
};