Camera2: Copy metadata buffers for streaming.
Using the passed-in buffer directly is incorrect; copy them so that
concurrent access can be controlled, and ownership is clear.
Bug: 6243944
Change-Id: Iad22c0dc166b7739e6c5dbfa39aac631b974c95a
diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp
index 6a1e9ea..b81d54c 100644
--- a/services/camera/libcameraservice/Camera2Device.cpp
+++ b/services/camera/libcameraservice/Camera2Device.cpp
@@ -302,6 +302,12 @@
mStreamSlotCount = 0;
return OK;
}
+ camera_metadata_t *buf2 = clone_camera_metadata(buf);
+ if (!buf2) {
+ ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
+ return NO_MEMORY;
+ }
+
if (mStreamSlotCount > 1) {
List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
@@ -309,9 +315,9 @@
}
if (mStreamSlotCount == 1) {
free_camera_metadata( *(mStreamSlot.begin()) );
- *(mStreamSlot.begin()) = buf;
+ *(mStreamSlot.begin()) = buf2;
} else {
- mStreamSlot.push_front(buf);
+ mStreamSlot.push_front(buf2);
mStreamSlotCount = 1;
}
return signalConsumerLocked();
@@ -322,11 +328,22 @@
{
ALOGV("%s: E", __FUNCTION__);
Mutex::Autolock l(mMutex);
+ status_t res;
+
if (mStreamSlotCount > 0) {
freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
}
- mStreamSlot = bufs;
- mStreamSlotCount = mStreamSlot.size();
+ mStreamSlotCount = 0;
+ for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
+ r != bufs.end(); r++) {
+ camera_metadata_t *r2 = clone_camera_metadata(*r);
+ if (!r2) {
+ ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
+ return NO_MEMORY;
+ }
+ mStreamSlot.push_back(r2);
+ mStreamSlotCount++;
+ }
return signalConsumerLocked();
}