summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShuzhen Wang <shuzhenw@codeaurora.org>2014-10-01 10:28:19 -0700
committerAli B <abittin@gmail.com>2018-06-17 19:19:52 +0300
commit4cec623a986e17eeb6501a5ad648ba56127f174a (patch)
treef420939ebed241ee1630c4f871c90fe9bca34f7c
parent42abd7e0b3f0288fe85ca995a11011bb5338fbe7 (diff)
Camera3: Rework flush functionality
We can have two output buffers per request for cases like ZSL. When doing flush the process capture result has to be called only once for each frame number and should contain all cancelled output buffers. Doing this on a buffer basis will result in unexpected frame number errors in the upper framework. The buffers should be again grouped depending on their frame number and returned back in single 'process_capture_result()' call. Bug: 17113762 Change-Id: I422e86debb2d8e5e8bca1d402479e42f02d915a4 Signed-off-by: Daniel Jarai <jaraidaniel@gmail.com>
-rwxr-xr-xcamera/QCamera2/HAL3/QCamera3HWI.cpp180
-rwxr-xr-xcamera/QCamera2/HAL3/QCamera3HWI.h3
2 files changed, 108 insertions, 75 deletions
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.cpp b/camera/QCamera2/HAL3/QCamera3HWI.cpp
index 2af506a..73f97a3 100755
--- a/camera/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/camera/QCamera2/HAL3/QCamera3HWI.cpp
@@ -1409,14 +1409,16 @@ void QCamera3HardwareInterface::dump(int /*fd*/)
*==========================================================================*/
int QCamera3HardwareInterface::flush()
{
-
unsigned int frameNum = 0;
camera3_notify_msg_t notify_msg;
camera3_capture_result_t result;
- camera3_stream_buffer_t pStream_Buf;
+ camera3_stream_buffer_t *pStream_Buf = NULL;
+ FlushMap flushMap;
ALOGV("%s: Unblocking Process Capture Request", __func__);
+ memset(&result, 0, sizeof(camera3_capture_result_t));
+
// Stop the Streams/Channels
for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
it != mStreamInfo.end(); it++) {
@@ -1439,110 +1441,138 @@ int QCamera3HardwareInterface::flush()
List<PendingRequestInfo>::iterator i = mPendingRequestsList.begin();
frameNum = i->frame_number;
- ALOGV("%s: Latest frame num on mPendingRequestsList = %d",
+ ALOGV("%s: Oldest frame num on mPendingRequestsList = %d",
__func__, frameNum);
- // Go through the pending buffers and send buffer errors
+ // Go through the pending buffers and group them depending
+ // on frame number
for (List<PendingBufferInfo>::iterator k =
- mPendingBuffersMap.mPendingBufferList.begin();
- k != mPendingBuffersMap.mPendingBufferList.end(); ) {
- ALOGV("%s: frame = %d, buffer = %p, stream = %p, stream format = %d",
- __func__, k->frame_number, k->buffer, k->stream,
- k->stream->format);
+ mPendingBuffersMap.mPendingBufferList.begin();
+ k != mPendingBuffersMap.mPendingBufferList.end();) {
if (k->frame_number < frameNum) {
- // Send Error notify to frameworks for each buffer for which
- // metadata buffer is already sent
- ALOGV("%s: Sending ERROR BUFFER for frame %d, buffer %p",
- __func__, k->frame_number, k->buffer);
-
- notify_msg.type = CAMERA3_MSG_ERROR;
- notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_BUFFER;
- notify_msg.message.error.error_stream = k->stream;
- notify_msg.message.error.frame_number = k->frame_number;
- mCallbackOps->notify(mCallbackOps, &notify_msg);
- ALOGV("%s: notify frame_number = %d", __func__,
- i->frame_number);
-
- pStream_Buf.acquire_fence = -1;
- pStream_Buf.release_fence = -1;
- pStream_Buf.buffer = k->buffer;
- pStream_Buf.status = CAMERA3_BUFFER_STATUS_ERROR;
- pStream_Buf.stream = k->stream;
-
- memset(&result, 0, sizeof(camera3_capture_result_t));
- result.result = NULL;
- result.frame_number = k->frame_number;
- result.num_output_buffers = 1;
- result.output_buffers = &pStream_Buf ;
- mCallbackOps->process_capture_result(mCallbackOps, &result);
+ ssize_t idx = flushMap.indexOfKey(k->frame_number);
+ if (idx == NAME_NOT_FOUND) {
+ Vector<PendingBufferInfo> pending;
+ pending.add(*k);
+ flushMap.add(k->frame_number, pending);
+ } else {
+ Vector<PendingBufferInfo> &pending =
+ flushMap.editValueFor(k->frame_number);
+ pending.add(*k);
+ }
mPendingBuffersMap.num_buffers--;
k = mPendingBuffersMap.mPendingBufferList.erase(k);
+ } else {
+ k++;
+ }
+ }
+
+ for (size_t i = 0; i < flushMap.size(); i++) {
+ uint32_t frame_number = flushMap.keyAt(i);
+ const Vector<PendingBufferInfo> &pending = flushMap.valueAt(i);
+
+ // Send Error notify to frameworks for each buffer for which
+ // metadata buffer is already sent
+ ALOGV("%s: Sending ERROR BUFFER for frame %d number of buffer %d",
+ __func__, frame_number, pending.size());
+
+ pStream_Buf = new camera3_stream_buffer_t[pending.size()];
+ if (NULL == pStream_Buf) {
+ ALOGE("%s: No memory for pending buffers array", __func__);
+ pthread_mutex_unlock(&mMutex);
+ return NO_MEMORY;
}
- else {
- k++;
+
+ for (size_t j = 0; j < pending.size(); j++) {
+ const PendingBufferInfo &info = pending.itemAt(j);
+ notify_msg.type = CAMERA3_MSG_ERROR;
+ notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_BUFFER;
+ notify_msg.message.error.error_stream = info.stream;
+ notify_msg.message.error.frame_number = frame_number;
+ pStream_Buf[j].acquire_fence = -1;
+ pStream_Buf[j].release_fence = -1;
+ pStream_Buf[j].buffer = info.buffer;
+ pStream_Buf[j].status = CAMERA3_BUFFER_STATUS_ERROR;
+ pStream_Buf[j].stream = info.stream;
+ mCallbackOps->notify(mCallbackOps, &notify_msg);
+ ALOGV("%s: notify frame_number = %d stream %p", __func__,
+ frame_number, info.stream);
}
+
+ result.result = NULL;
+ result.frame_number = frame_number;
+ result.num_output_buffers = pending.size();
+ result.output_buffers = pStream_Buf;
+ mCallbackOps->process_capture_result(mCallbackOps, &result);
+
+ delete [] pStream_Buf;
}
ALOGV("%s:Sending ERROR REQUEST for all pending requests", __func__);
+ flushMap.clear();
+ for (List<PendingBufferInfo>::iterator k =
+ mPendingBuffersMap.mPendingBufferList.begin();
+ k != mPendingBuffersMap.mPendingBufferList.end();) {
+ ssize_t idx = flushMap.indexOfKey(k->frame_number);
+ if (idx == NAME_NOT_FOUND) {
+ Vector<PendingBufferInfo> pending;
+ pending.add(*k);
+ flushMap.add(k->frame_number, pending);
+ } else {
+ Vector<PendingBufferInfo> &pending =
+ flushMap.editValueFor(k->frame_number);
+ pending.add(*k);
+ }
+
+ mPendingBuffersMap.num_buffers--;
+ k = mPendingBuffersMap.mPendingBufferList.erase(k);
+ }
+
// Go through the pending requests info and send error request to framework
- for (i = mPendingRequestsList.begin(); i != mPendingRequestsList.end(); ) {
- int numBuffers = 0;
+ for (size_t i = 0; i < flushMap.size(); i++) {
+ uint32_t frame_number = flushMap.keyAt(i);
+ const Vector<PendingBufferInfo> &pending = flushMap.valueAt(i);
ALOGV("%s:Sending ERROR REQUEST for frame %d",
- __func__, i->frame_number);
+ __func__, frame_number);
// Send shutter notify to frameworks
notify_msg.type = CAMERA3_MSG_ERROR;
notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
notify_msg.message.error.error_stream = NULL;
- notify_msg.message.error.frame_number = i->frame_number;
+ notify_msg.message.error.frame_number = frame_number;
mCallbackOps->notify(mCallbackOps, &notify_msg);
- memset(&result, 0, sizeof(camera3_capture_result_t));
- result.frame_number = i->frame_number;
- result.num_output_buffers = 0;
- result.output_buffers = NULL;
- numBuffers = 0;
-
- for (List<PendingBufferInfo>::iterator k =
- mPendingBuffersMap.mPendingBufferList.begin();
- k != mPendingBuffersMap.mPendingBufferList.end(); ) {
- if (k->frame_number == i->frame_number) {
- ALOGV("%s: Sending Error for frame = %d, buffer = %p,"
- " stream = %p, stream format = %d",__func__,
- k->frame_number, k->buffer, k->stream, k->stream->format);
-
- pStream_Buf.acquire_fence = -1;
- pStream_Buf.release_fence = -1;
- pStream_Buf.buffer = k->buffer;
- pStream_Buf.status = CAMERA3_BUFFER_STATUS_ERROR;
- pStream_Buf.stream = k->stream;
-
- result.num_output_buffers = 1;
- result.output_buffers = &pStream_Buf;
- result.result = NULL;
- result.frame_number = i->frame_number;
+ pStream_Buf = new camera3_stream_buffer_t[pending.size()];
+ if (NULL == pStream_Buf) {
+ ALOGE("%s: No memory for pending buffers array", __func__);
+ pthread_mutex_unlock(&mMutex);
+ return NO_MEMORY;
+ }
- mCallbackOps->process_capture_result(mCallbackOps, &result);
- mPendingBuffersMap.num_buffers--;
- k = mPendingBuffersMap.mPendingBufferList.erase(k);
- numBuffers++;
- }
- else {
- k++;
- }
+ for (size_t j = 0; j < pending.size(); j++) {
+ const PendingBufferInfo &info = pending.itemAt(j);
+ pStream_Buf[j].acquire_fence = -1;
+ pStream_Buf[j].release_fence = -1;
+ pStream_Buf[j].buffer = info.buffer;
+ pStream_Buf[j].status = CAMERA3_BUFFER_STATUS_ERROR;
+ pStream_Buf[j].stream = info.stream;
}
- ALOGV("%s: mPendingBuffersMap.num_buffers = %d",
- __func__, mPendingBuffersMap.num_buffers);
- i = mPendingRequestsList.erase(i);
+ result.num_output_buffers = pending.size();
+ result.output_buffers = pStream_Buf;
+ result.result = NULL;
+ result.frame_number = frame_number;
+ mCallbackOps->process_capture_result(mCallbackOps, &result);
+ delete [] pStream_Buf;
}
/* Reset pending buffer list and requests list */
mPendingRequestsList.clear();
+ flushMap.clear();
mPendingBuffersMap.num_buffers = 0;
mPendingBuffersMap.mPendingBufferList.clear();
ALOGV("%s: Cleared all the pending buffers ", __func__);
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.h b/camera/QCamera2/HAL3/QCamera3HWI.h
index 4294432..319f813 100755
--- a/camera/QCamera2/HAL3/QCamera3HWI.h
+++ b/camera/QCamera2/HAL3/QCamera3HWI.h
@@ -233,6 +233,9 @@ private:
} PendingBuffersMap;
List<MetadataBufferInfo> mStoredMetadataList;
+
+ typedef KeyedVector<uint32_t, Vector<PendingBufferInfo> > FlushMap;
+
List<PendingRequestInfo> mPendingRequestsList;
PendingBuffersMap mPendingBuffersMap;
pthread_cond_t mRequestCond;