Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6773d477 authored by Praveen Chavan's avatar Praveen Chavan Committed by Chien-Yu Chen
Browse files

camera: Add support to pass native handles across binders

If the video buffer contains a native handle, serialize and
deserialize it properly.

Author: spodder@codeaurora.org
Bug: 26268807
Change-Id: I1905be81e2045667e00c95ab75d1bf144756b894
parent 98a668f6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_C_INCLUDES += \
	system/media/camera/include \
	system/media/private/camera/include \
	frameworks/native/include/media/openmax \

LOCAL_MODULE:= libcamera_client

+15 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
//#define LOG_NDEBUG 0

#include <camera/CameraUtils.h>
#include <media/hardware/HardwareAPI.h>

#include <system/window.h>
#include <system/graphics.h>
@@ -121,5 +122,19 @@ status_t CameraUtils::getRotationTransform(const CameraMetadata& staticInfo,
    return OK;
}

// Return whether the image data contains a native handle.
bool CameraUtils::isNativeHandleMetadata(const sp<IMemory>& imageData) {
    if (imageData == nullptr) {
        return false;
    }

    if (imageData->size() == sizeof(VideoNativeHandleMetadata)) {
        VideoNativeHandleMetadata *metadata =
                (VideoNativeHandleMetadata*)(imageData->pointer());
        return metadata->eType == kMetadataBufferTypeNativeHandleSource;
    }

    return false;
}

} /* namespace android */
+25 −0
Original line number Diff line number Diff line
@@ -21,9 +21,11 @@
#include <stdint.h>
#include <sys/types.h>
#include <binder/Parcel.h>
#include <camera/CameraUtils.h>
#include <camera/ICamera.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/Surface.h>
#include <media/hardware/HardwareAPI.h>

namespace android {

@@ -149,7 +151,22 @@ public:
        Parcel data, reply;
        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
        data.writeStrongBinder(IInterface::asBinder(mem));

        native_handle_t *nh = nullptr;
        if (CameraUtils::isNativeHandleMetadata(mem)) {
            VideoNativeHandleMetadata *metadata =
                        (VideoNativeHandleMetadata*)(mem->pointer());
            nh = metadata->pHandle;
            data.writeNativeHandle(nh);
        }

        remote()->transact(RELEASE_RECORDING_FRAME, data, &reply);

        if (nh) {
            // Close the native handle because camera received a dup copy.
            native_handle_close(nh);
            native_handle_delete(nh);
        }
    }

    status_t setVideoBufferMode(int32_t videoBufferMode)
@@ -348,6 +365,14 @@ status_t BnCamera::onTransact(
            ALOGV("RELEASE_RECORDING_FRAME");
            CHECK_INTERFACE(ICamera, data, reply);
            sp<IMemory> mem = interface_cast<IMemory>(data.readStrongBinder());

            if (CameraUtils::isNativeHandleMetadata(mem)) {
                VideoNativeHandleMetadata *metadata =
                        (VideoNativeHandleMetadata*)(mem->pointer());
                metadata->pHandle = data.readNativeHandle();
                // releaseRecordingFrame will be responsble to close the native handle.
            }

            releaseRecordingFrame(mem);
            return NO_ERROR;
        } break;
+30 −8
Original line number Diff line number Diff line
@@ -20,7 +20,9 @@
#include <utils/Log.h>
#include <stdint.h>
#include <sys/types.h>
#include <camera/CameraUtils.h>
#include <camera/ICameraClient.h>
#include <media/hardware/HardwareAPI.h>

namespace android {

@@ -75,6 +77,13 @@ public:
        data.writeInt64(timestamp);
        data.writeInt32(msgType);
        data.writeStrongBinder(IInterface::asBinder(imageData));
        // If imageData is metadata and it contains a native handle, write the native handle to
        // parcel.
        if (CameraUtils::isNativeHandleMetadata(imageData)) {
            VideoNativeHandleMetadata *metadata =
                    (VideoNativeHandleMetadata*)(imageData->pointer());
            data.writeNativeHandle(metadata->pHandle);
        }
        remote()->transact(DATA_CALLBACK_TIMESTAMP, data, &reply, IBinder::FLAG_ONEWAY);
    }
};
@@ -118,6 +127,19 @@ status_t BnCameraClient::onTransact(
            nsecs_t timestamp = data.readInt64();
            int32_t msgType = data.readInt32();
            sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());

            // If the image data contains a native handle, read the native handle from the parcel
            // and replace the native handle in the image data. (The native handle in image data is
            // not serielized/deserialized so it's not valid in the process.)
            if (CameraUtils::isNativeHandleMetadata(imageData)) {
                VideoNativeHandleMetadata *metadata =
                        (VideoNativeHandleMetadata*)(imageData->pointer());
                metadata->pHandle = data.readNativeHandle();

                // The native handle will be freed in
                // BpCameraRecordingProxyListener::releaseRecordingFrame.
            }

            dataCallbackTimestamp(timestamp, msgType, imageData);
            return NO_ERROR;
        } break;
+26 −0
Original line number Diff line number Diff line
@@ -16,10 +16,12 @@

//#define LOG_NDEBUG 0
#define LOG_TAG "ICameraRecordingProxy"
#include <camera/CameraUtils.h>
#include <camera/ICameraRecordingProxy.h>
#include <camera/ICameraRecordingProxyListener.h>
#include <binder/IMemory.h>
#include <binder/Parcel.h>
#include <media/hardware/HardwareAPI.h>
#include <stdint.h>
#include <utils/Log.h>

@@ -64,7 +66,22 @@ public:
        Parcel data, reply;
        data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
        data.writeStrongBinder(IInterface::asBinder(mem));

        native_handle_t *nh = nullptr;
        if (CameraUtils::isNativeHandleMetadata(mem)) {
            VideoNativeHandleMetadata *metadata =
                        (VideoNativeHandleMetadata*)(mem->pointer());
            nh = metadata->pHandle;
            data.writeNativeHandle(nh);
        }

        remote()->transact(RELEASE_RECORDING_FRAME, data, &reply);

        if (nh) {
            // Close the native handle because camera received a dup copy.
            native_handle_close(nh);
            native_handle_delete(nh);
        }
    }
};

@@ -94,7 +111,16 @@ status_t BnCameraRecordingProxy::onTransact(
            ALOGV("RELEASE_RECORDING_FRAME");
            CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
            sp<IMemory> mem = interface_cast<IMemory>(data.readStrongBinder());

            if (CameraUtils::isNativeHandleMetadata(mem)) {
                VideoNativeHandleMetadata *metadata =
                        (VideoNativeHandleMetadata*)(mem->pointer());
                metadata->pHandle = data.readNativeHandle();

                // releaseRecordingFrame will be responsble to close the native handle.
            }
            releaseRecordingFrame(mem);

            return NO_ERROR;
        } break;

Loading