Camera3: Fix rapid ZSL snapshots
-In case of rapid back to back snapshots framework
reuses ZSL YUV frame
-Remove code in HAL which assumes that once a buffer
is passed as input it will not be used again
Change-Id: I72a0f527de99b96508c7020455a47bfe754d9df4
diff --git a/camera/QCamera2/HAL3/QCamera3Channel.cpp b/camera/QCamera2/HAL3/QCamera3Channel.cpp
index f07b756..9bf5ee9 100755
--- a/camera/QCamera2/HAL3/QCamera3Channel.cpp
+++ b/camera/QCamera2/HAL3/QCamera3Channel.cpp
@@ -843,6 +843,15 @@
int maxJpegSize;
QCamera3PicChannel *obj = (QCamera3PicChannel *)userdata;
if (obj) {
+
+ //Release any cached metabuffer information
+ if (obj->mMetaFrame != NULL && obj->m_pMetaChannel != NULL) {
+ ((QCamera3MetadataChannel*)(obj->m_pMetaChannel))->bufDone(obj->mMetaFrame);
+ obj->mMetaFrame = NULL;
+ obj->m_pMetaChannel = NULL;
+ } else {
+ ALOGE("%s: Meta frame was NULL", __func__);
+ }
//Construct payload for process_capture_result. Call mChannelCb
qcamera_jpeg_data_t *job = obj->m_postprocessor.findJpegJobByJobId(jobId);
@@ -914,7 +923,8 @@
mJpegSettings(NULL),
mCurrentBufIndex(-1),
mMemory(NULL),
- mYuvMemory(NULL)
+ mYuvMemory(NULL),
+ mMetaFrame(NULL)
{
int32_t rc = m_postprocessor.init(jpegEvtHandle, this);
if (rc != 0) {
@@ -1260,8 +1270,13 @@
return rotation;
}
-void QCamera3PicChannel::queueMetadata(mm_camera_super_buf_t *metadata_buf)
+void QCamera3PicChannel::queueMetadata(mm_camera_super_buf_t *metadata_buf,
+ QCamera3Channel *pMetaChannel,
+ bool relinquish)
{
+ if(relinquish)
+ mMetaFrame = metadata_buf;
+ m_pMetaChannel = pMetaChannel;
m_postprocessor.processPPMetadata(metadata_buf);
}
/*===========================================================================
@@ -1755,7 +1770,6 @@
picChHandle(ch_hdl),
m_pSrcChannel(NULL),
m_pMetaChannel(NULL),
- m_metaFrame(NULL),
mMemory(NULL)
{
memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
@@ -1837,12 +1851,6 @@
return;
}
*frame = *super_frame;
- //queue back the metadata buffer
- if (m_metaFrame != NULL) {
- metadataBufDone(m_metaFrame);
- } else {
- ALOGE("%s: Meta frame was NULL", __func__);
- }
obj->m_postprocessor.processPPData(frame);
return;
}
@@ -1858,8 +1866,7 @@
*==========================================================================*/
QCamera3ReprocessChannel::QCamera3ReprocessChannel() :
m_pSrcChannel(NULL),
- m_pMetaChannel(NULL),
- m_metaFrame(NULL)
+ m_pMetaChannel(NULL)
{
}
@@ -2003,7 +2010,6 @@
ALOGE("%s: No source channel for reprocess", __func__);
return -1;
}
- m_metaFrame = meta_frame;
for (int i = 0; i < frame->num_bufs; i++) {
QCamera3Stream *pStream = getStreamBySourceHandle(frame->bufs[i]->stream_id);
if (pStream != NULL) {
diff --git a/camera/QCamera2/HAL3/QCamera3Channel.h b/camera/QCamera2/HAL3/QCamera3Channel.h
index 05526cd..ad7b35e 100755
--- a/camera/QCamera2/HAL3/QCamera3Channel.h
+++ b/camera/QCamera2/HAL3/QCamera3Channel.h
@@ -229,7 +229,9 @@
void *userdata);
static void dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
void *userdata);
- void queueMetadata(mm_camera_super_buf_t *metadata_buf);
+ void queueMetadata(mm_camera_super_buf_t *metadata_buf,
+ QCamera3Channel *pMetaChannel,
+ bool relinquish);
public:
static int kMaxBuffers;
@@ -245,6 +247,8 @@
QCamera3GrallocMemory *mMemory;
QCamera3HeapMemory *mYuvMemory;
+ QCamera3Channel *m_pMetaChannel;
+ mm_camera_super_buf_t *mMetaFrame;
};
// reprocess channel class
@@ -283,7 +287,6 @@
uint32_t mSrcStreamHandles[MAX_STREAM_NUM_IN_BUNDLE];
QCamera3Channel *m_pSrcChannel; // ptr to source channel for reprocess
QCamera3Channel *m_pMetaChannel;
- mm_camera_super_buf_t *m_metaFrame;
QCamera3HeapMemory *mMemory;
};
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.cpp b/camera/QCamera2/HAL3/QCamera3HWI.cpp
index cbce057..556432a 100755
--- a/camera/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/camera/QCamera2/HAL3/QCamera3HWI.cpp
@@ -1078,12 +1078,12 @@
ALOGD("Stream id: %d", pInputBuffer->stream_id);
ALOGD("streamtype:%d", pInputBuffer->stream_type);
ALOGD("frame len:%d", pInputBuffer->frame_len);
+ ALOGD("Handle:%p", request->input_buffer->buffer);
//TODO: need to get corresponding metadata and send it to pproc
for (List<MetadataBufferInfo>::iterator m = mStoredMetadataList.begin();
m != mStoredMetadataList.end(); m++) {
if (m->zsl_buf_hdl == request->input_buffer->buffer) {
reproc_meta.meta_buf = m->meta_buf;
- m = mStoredMetadataList.erase(m);
queueMetadata = 1;
break;
}
@@ -1093,7 +1093,7 @@
rc = channel->request(output.buffer, frameNumber, mJpegSettings,
pInputBuffer,(QCamera3Channel*)inputChannel);
if (queueMetadata) {
- mPictureChannel->queueMetadata(reproc_meta.meta_buf);
+ mPictureChannel->queueMetadata(reproc_meta.meta_buf,mMetadataChannel,false);
}
} else {
ALOGE("%s: %d, request with buffer %p, frame_number %d", __func__,
@@ -1301,7 +1301,7 @@
j != i->buffers.end(); j++){
if (j->stream->stream_type == CAMERA3_STREAM_OUTPUT &&
j->stream->format == HAL_PIXEL_FORMAT_BLOB) {
- mPictureChannel->queueMetadata(metadata_buf);
+ mPictureChannel->queueMetadata(metadata_buf,mMetadataChannel,true);
break;
}
}
@@ -1313,7 +1313,7 @@
}
} else if (!mIsZslMode && i->blob_request) {
//If it is a blob request then send the metadata to the picture channel
- mPictureChannel->queueMetadata(metadata_buf);
+ mPictureChannel->queueMetadata(metadata_buf,mMetadataChannel,true);
} else {
// Return metadata buffer
mMetadataChannel->bufDone(metadata_buf);