Camera: Fix passing video native handle for 64-bit app
Add new binder calls to pass video native handle so the video native
handle can be passed between 32-bit and 64-bit processes.
Remove problematic code that used IMemory to pass video native
handle because the sizes of VideoNativeMetadata are different in
32-bit and 64-bit processes.
Bug: 28403412
Change-Id: I3341b1812ecc41d61846bb72ca926ecb1674c9ec
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 4eb7b03..c8e64fe 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -1242,6 +1242,12 @@
ALOGW("%s: Not supported in buffer queue mode.", __FUNCTION__);
}
+void Camera2Client::releaseRecordingFrameHandle(native_handle_t *handle) {
+ (void)handle;
+ ATRACE_CALL();
+ ALOGW("%s: Not supported in buffer queue mode.", __FUNCTION__);
+}
+
status_t Camera2Client::autoFocus() {
ATRACE_CALL();
Mutex::Autolock icl(mBinderSerializationLock);
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index 12ee157..3cb9e4f 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -71,6 +71,7 @@
virtual void stopRecording();
virtual bool recordingEnabled();
virtual void releaseRecordingFrame(const sp<IMemory>& mem);
+ virtual void releaseRecordingFrameHandle(native_handle_t *handle);
virtual status_t autoFocus();
virtual status_t cancelAutoFocus();
virtual status_t takePicture(int msgType);
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index d2fedf8..266fb03 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -19,6 +19,7 @@
#include <cutils/properties.h>
#include <gui/Surface.h>
+#include <media/hardware/HardwareAPI.h>
#include "api1/CameraClient.h"
#include "device1/CameraHardwareInterface.h"
@@ -488,6 +489,39 @@
mHardware->releaseRecordingFrame(mem);
}
+void CameraClient::releaseRecordingFrameHandle(native_handle_t *handle) {
+ if (handle == nullptr) return;
+
+ sp<IMemory> dataPtr;
+ {
+ Mutex::Autolock l(mAvailableCallbackBuffersLock);
+ if (!mAvailableCallbackBuffers.empty()) {
+ dataPtr = mAvailableCallbackBuffers.back();
+ mAvailableCallbackBuffers.pop_back();
+ }
+ }
+
+ if (dataPtr == nullptr) {
+ ALOGE("%s: %d: No callback buffer available. Dropping a native handle.", __FUNCTION__,
+ __LINE__);
+ native_handle_close(handle);
+ native_handle_delete(handle);
+ return;
+ } else if (dataPtr->size() != sizeof(VideoNativeHandleMetadata)) {
+ ALOGE("%s: %d: Callback buffer size doesn't match VideoNativeHandleMetadata", __FUNCTION__,
+ __LINE__);
+ native_handle_close(handle);
+ native_handle_delete(handle);
+ return;
+ }
+
+ VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(dataPtr->pointer());
+ metadata->eType = kMetadataBufferTypeNativeHandleSource;
+ metadata->pHandle = handle;
+
+ mHardware->releaseRecordingFrame(dataPtr);
+}
+
status_t CameraClient::setVideoBufferMode(int32_t videoBufferMode) {
LOG1("setVideoBufferMode: %d", videoBufferMode);
bool enableMetadataInBuffers = false;
@@ -929,8 +963,28 @@
int32_t msgType, const sp<IMemory>& dataPtr) {
sp<hardware::ICameraClient> c = mRemoteCallback;
mLock.unlock();
- if (c != 0) {
- c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
+ if (c != 0 && dataPtr != nullptr) {
+ native_handle_t* handle = nullptr;
+
+ // Check if dataPtr contains a VideoNativeHandleMetadata.
+ if (dataPtr->size() == sizeof(VideoNativeHandleMetadata)) {
+ VideoNativeHandleMetadata *metadata =
+ (VideoNativeHandleMetadata*)(dataPtr->pointer());
+ if (metadata->eType == kMetadataBufferTypeNativeHandleSource) {
+ handle = metadata->pHandle;
+ }
+ }
+
+ // If dataPtr contains a native handle, send it via recordingFrameHandleCallbackTimestamp.
+ if (handle != nullptr) {
+ {
+ Mutex::Autolock l(mAvailableCallbackBuffersLock);
+ mAvailableCallbackBuffers.push_back(dataPtr);
+ }
+ c->recordingFrameHandleCallbackTimestamp(timestamp, handle);
+ } else {
+ c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
+ }
}
}
diff --git a/services/camera/libcameraservice/api1/CameraClient.h b/services/camera/libcameraservice/api1/CameraClient.h
index 603fd17..4f46fc4 100644
--- a/services/camera/libcameraservice/api1/CameraClient.h
+++ b/services/camera/libcameraservice/api1/CameraClient.h
@@ -49,6 +49,7 @@
virtual void stopRecording();
virtual bool recordingEnabled();
virtual void releaseRecordingFrame(const sp<IMemory>& mem);
+ virtual void releaseRecordingFrameHandle(native_handle_t *handle);
virtual status_t autoFocus();
virtual status_t cancelAutoFocus();
virtual status_t takePicture(int msgType);
@@ -148,6 +149,12 @@
// Debugging information
CameraParameters mLatestSetParameters;
+ // mAvailableCallbackBuffers stores sp<IMemory> that HAL uses to send VideoNativeHandleMetadata.
+ // It will be used to send VideoNativeHandleMetadata back to HAL when camera receives the
+ // native handle from releaseRecordingFrameHandle.
+ Mutex mAvailableCallbackBuffersLock;
+ std::vector<sp<IMemory>> mAvailableCallbackBuffers;
+
// We need to avoid the deadlock when the incoming command thread and
// the CameraHardwareInterface callback thread both want to grab mLock.
// An extra flag is used to tell the callback thread that it should stop