QCamera2: HAL3: Restart daemon and mediaserver when buffer is lost.
When there are buffers not returned during closeCamera, restart
both daemon and mediaserver to reclaim leaked memory.
Bug: 25149843
Bug: 27529887
Change-Id: I5283d37e04ab6e7b0305db5821a38a83f3ae5126
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.cpp b/camera/QCamera2/HAL3/QCamera3HWI.cpp
index 57cad30..1d86d19 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/camera/QCamera2/HAL3/QCamera3HWI.cpp
@@ -297,6 +297,8 @@
mEnableRawDump = atoi(prop);
if (mEnableRawDump)
CDBG("%s: Raw dump from Camera HAL enabled", __func__);
+
+ mPendingBuffersMap.num_buffers = 0;
}
/*===========================================================================
@@ -313,6 +315,7 @@
CDBG("%s: E", __func__);
/* We need to stop all streams before deleting any stream */
+ bool hasPendingBuffers = (mPendingBuffersMap.num_buffers > 0);
if (mRawDumpChannel) {
mRawDumpChannel->stop();
@@ -355,6 +358,19 @@
delete mMetadataChannel;
mMetadataChannel = NULL;
}
+
+ memset(mParameters, 0, sizeof(parm_buffer_t));
+ // Check if there is still pending buffer not yet returned.
+ if (hasPendingBuffers) {
+ uint8_t restart = TRUE;
+ AddSetParmEntryToBatch(mParameters, CAM_INTF_META_DAEMON_RESTART,
+ sizeof(restart), &restart);
+ }
+
+ int rc = mCameraHandle->ops->set_parms(mCameraHandle->camera_handle, mParameters);
+ if (rc < 0) {
+ ALOGE("%s: set_parms failed for unconfigure", __func__);
+ }
deinitParameters();
}
@@ -372,6 +388,11 @@
pthread_cond_destroy(&mRequestCond);
pthread_mutex_destroy(&mMutex);
+
+ if (hasPendingBuffers) {
+ ALOGE("%s: Not all buffers are returned. Aborting...", __func__);
+ abort();
+ }
CDBG("%s: X", __func__);
}
diff --git a/camera/QCamera2/stack/common/cam_intf.h b/camera/QCamera2/stack/common/cam_intf.h
index aad8b02..9b5fc7a 100644
--- a/camera/QCamera2/stack/common/cam_intf.h
+++ b/camera/QCamera2/stack/common/cam_intf.h
@@ -641,6 +641,7 @@
INCLUDE(CAM_INTF_PARM_ROTATION, cam_rotation_info_t, 1);
INCLUDE(CAM_INTF_META_EFFECTIVE_EXPOSURE_FACTOR, float, 1);
INCLUDE(CAM_INTF_META_USE_AV_TIMER, uint8_t, 1);
+ INCLUDE(CAM_INTF_META_DAEMON_RESTART, uint8_t, 1);
} parm_data_t;
typedef parm_data_t metadata_data_t;
diff --git a/camera/QCamera2/stack/common/cam_types.h b/camera/QCamera2/stack/common/cam_types.h
index 5a75d8f..ac0502e 100644
--- a/camera/QCamera2/stack/common/cam_types.h
+++ b/camera/QCamera2/stack/common/cam_types.h
@@ -1356,6 +1356,8 @@
CAM_INTF_PARM_CAC,
CAM_INTF_META_EFFECTIVE_EXPOSURE_FACTOR,
CAM_INTF_META_USE_AV_TIMER,
+ /* Whether HAL has run into DRAIN error */
+ CAM_INTF_META_DAEMON_RESTART,
CAM_INTF_PARM_MAX
} cam_intf_parm_type_t;
diff --git a/camera/QCamera2/stack/mm-camera-interface/src/cam_intf.c b/camera/QCamera2/stack/mm-camera-interface/src/cam_intf.c
index 119c967..1676f75 100644
--- a/camera/QCamera2/stack/mm-camera-interface/src/cam_intf.c
+++ b/camera/QCamera2/stack/mm-camera-interface/src/cam_intf.c
@@ -343,6 +343,8 @@
return POINTER_OF_META(CAM_INTF_PARM_ROTATION, metadata);
case CAM_INTF_META_USE_AV_TIMER:
return POINTER_OF_META(CAM_INTF_META_USE_AV_TIMER, metadata);
+ case CAM_INTF_META_DAEMON_RESTART:
+ return POINTER_OF_META(CAM_INTF_META_DAEMON_RESTART, metadata);
default:
return NULL;
}
@@ -662,6 +664,8 @@
return SIZE_OF_PARAM(CAM_INTF_PARM_ROTATION, metadata);
case CAM_INTF_META_USE_AV_TIMER:
return SIZE_OF_PARAM(CAM_INTF_META_USE_AV_TIMER, metadata);
+ case CAM_INTF_META_DAEMON_RESTART:
+ return SIZE_OF_PARAM(CAM_INTF_META_DAEMON_RESTART, metadata);
default:
return 0;
}