QCamera2: fix a race condition during take_picture
When take_picture is called for regular capture, streams in preview
channel will be stopped, therefore gralloc memories will be cancelled
to queue back to gralloc. However, preview callback still not disabled
and when process preview frames in callback, it will again dequeue
from gralloc. When capture channel is created, postview is also
using gralloc memory, since the previous client still hold buffers,
gralloc memory allocation would fail. Fix this race condition by
changing statemachine to pic_taking state before call takePicture
would avoid preview callback prccess any frames after prevuew channel
is stopped.
Change-Id: I240ff594a78fe724bfa6e0710b7d1b22961e6c7f
diff --git a/QCamera2/HAL/QCameraStateMachine.cpp b/QCamera2/HAL/QCameraStateMachine.cpp
index 44ff872..42fe32e 100644
--- a/QCamera2/HAL/QCameraStateMachine.cpp
+++ b/QCamera2/HAL/QCameraStateMachine.cpp
@@ -1090,31 +1090,36 @@
case QCAMERA_SM_EVT_TAKE_PICTURE:
{
if ( m_parent->mParameters.getRecordingHintValue() == false) {
- rc = m_parent->takePicture();
- if (rc == NO_ERROR) {
- // move state to picture taking state
if (m_parent->isZSLMode()) {
m_state = QCAMERA_SM_STATE_PREVIEW_PIC_TAKING;
+ rc = m_parent->takePicture();
+ if (rc != NO_ERROR) {
+ // move state to previewing state
+ m_state = QCAMERA_SM_STATE_PREVIEWING;
+ }
} else {
m_state = QCAMERA_SM_STATE_PIC_TAKING;
+ rc = m_parent->takePicture();
+ if (rc != NO_ERROR) {
+ // move state to preview stopped state
+ m_state = QCAMERA_SM_STATE_PREVIEW_STOPPED;
+ }
}
- } else {
- // move state to preview stopped state
- m_state = QCAMERA_SM_STATE_PREVIEW_STOPPED;
- }
- result.status = rc;
- result.request_api = evt;
- result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
- m_parent->signalAPIResult(&result);
+
+ result.status = rc;
+ result.request_api = evt;
+ result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
+ m_parent->signalAPIResult(&result);
} else {
+ m_state = QCAMERA_SM_STATE_PREVIEW_PIC_TAKING;
rc = m_parent->takeLiveSnapshot();
- if (rc == NO_ERROR ) {
- m_state = QCAMERA_SM_STATE_PREVIEW_PIC_TAKING;
- result.status = rc;
- result.request_api = evt;
- result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
- m_parent->signalAPIResult(&result);
+ if (rc != NO_ERROR ) {
+ m_state = QCAMERA_SM_STATE_PREVIEWING;
}
+ result.status = rc;
+ result.request_api = evt;
+ result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
+ m_parent->signalAPIResult(&result);
}
}
break;