diff options
| author | Shuzhen Wang <shuzhenw@codeaurora.org> | 2014-10-01 10:28:19 -0700 |
|---|---|---|
| committer | Ali B <abittin@gmail.com> | 2018-06-17 19:19:52 +0300 |
| commit | 4cec623a986e17eeb6501a5ad648ba56127f174a (patch) | |
| tree | f420939ebed241ee1630c4f871c90fe9bca34f7c | |
| parent | 42abd7e0b3f0288fe85ca995a11011bb5338fbe7 (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-x | camera/QCamera2/HAL3/QCamera3HWI.cpp | 180 | ||||
| -rwxr-xr-x | camera/QCamera2/HAL3/QCamera3HWI.h | 3 |
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, ¬ify_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, ¬ify_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, ¬ify_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; |
