Loading camera/device/1.0/ICameraDevice.hal +14 −0 Original line number Diff line number Diff line Loading @@ -327,6 +327,20 @@ interface ICameraDevice { */ releaseRecordingFrameHandle(MemoryId memId, uint32_t bufferIndex, handle frame); /** * Release a batch of record frames previously returned by CAMERA_MSG_VIDEO_FRAME * in handleCallbackTimestampBatch. * * It is camera HAL client's responsibility to release video recording * frames sent out by the camera HAL before the camera HAL receives a call * to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives the call to * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is the camera HAL's * responsibility to manage the life-cycle of the video recording frames. * * @param batch A batch of recording frames to be released by camera HAL. */ releaseRecordingFrameHandleBatch(vec<VideoFrameMessage> batch); /** * Start auto focus. * Loading camera/device/1.0/ICameraDeviceCallback.hal +16 −2 Original line number Diff line number Diff line Loading @@ -92,10 +92,24 @@ interface ICameraDeviceCallback { * @param timestamp The time this buffer was captured by the camera, in * nanoseconds. * * @return frameId a frame ID to be used with releaseRecordingFrameId later * */ handleCallbackTimestamp(DataCallbackMsg msgType, handle frameData, MemoryId data, uint32_t bufferIndex, int64_t timestamp); /** * Send a batch of image data buffer to the camera service, with timestamps * * This callback can be used to send multiple frames to camera framework in one callback, which * reduce number of callbacks in performance intensive use cases, such as high speed video * recording. The HAL must not mix use of this method with handleCallbackTimestamp in one * recording session (between startRecording and stopRecording) * * @param msgType The kind of image buffer data this call represents. * @param batch a vector messages. Each message contains a image buffer and a timestamp. The * messages must be ordered in time from lower index to higher index, so that timestamp of * i-th message is always smaller than i+1-th message. * */ handleCallbackTimestampBatch(DataCallbackMsg msgType, vec<HandleTimestampMessage> batch); }; camera/device/1.0/default/CameraDevice.cpp +45 −2 Original line number Diff line number Diff line Loading @@ -420,6 +420,39 @@ void CameraDevice::sDataCb(int32_t msg_type, const camera_memory_t *data, unsign } } void CameraDevice::handleCallbackTimestamp( nsecs_t timestamp, int32_t msg_type, MemoryId memId , unsigned index, native_handle_t* handle) { uint32_t batchSize = 0; { Mutex::Autolock _l(mBatchLock); batchSize = mBatchSize; } if (batchSize == 0) { // non-batch mode mDeviceCallback->handleCallbackTimestamp( (DataCallbackMsg) msg_type, handle, memId, index, timestamp); } else { // batch mode Mutex::Autolock _l(mBatchLock); size_t inflightSize = mInflightBatch.size(); if (inflightSize == 0) { mBatchMsgType = msg_type; } else if (mBatchMsgType != msg_type) { ALOGE("%s: msg_type change (from %d to %d) is not supported!", __FUNCTION__, mBatchMsgType, msg_type); return; } mInflightBatch.push_back({handle, memId, index, timestamp}); // Send batched frames to camera framework if (mInflightBatch.size() >= batchSize) { mDeviceCallback->handleCallbackTimestampBatch( (DataCallbackMsg) mBatchMsgType, mInflightBatch); mInflightBatch.clear(); } } } void CameraDevice::sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type, const camera_memory_t *data, unsigned index, void *user) { ALOGV("%s", __FUNCTION__); Loading Loading @@ -450,8 +483,7 @@ void CameraDevice::sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type, object->mDeviceCallback->dataCallbackTimestamp( (DataCallbackMsg) msg_type, mem->handle.mId, index, timestamp); } else { object->mDeviceCallback->handleCallbackTimestamp( (DataCallbackMsg) msg_type, handle, mem->handle.mId, index, timestamp); object->handleCallbackTimestamp(timestamp, msg_type, mem->handle.mId, index, handle); } } } Loading Loading @@ -827,6 +859,17 @@ Return<void> CameraDevice::releaseRecordingFrameHandle( return Void(); } Return<void> CameraDevice::releaseRecordingFrameHandleBatch( const hidl_vec<VideoFrameMessage>& msgs) { ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); Mutex::Autolock _l(mLock); for (auto& msg : msgs) { releaseRecordingFrameLocked( msg.data, msg.bufferIndex, msg.frameData.getNativeHandle()); } return Void(); } Return<Status> CameraDevice::autoFocus() { ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); Mutex::Autolock _l(mLock); Loading camera/device/1.0/default/CameraDevice_1_0.h +15 −3 Original line number Diff line number Diff line Loading @@ -93,6 +93,8 @@ struct CameraDevice : public ICameraDevice { Return<void> releaseRecordingFrame(uint32_t memId, uint32_t bufferIndex) override; Return<void> releaseRecordingFrameHandle( uint32_t memId, uint32_t bufferIndex, const hidl_handle& frame) override; Return<void> releaseRecordingFrameHandleBatch( const hidl_vec<VideoFrameMessage>&) override; Return<Status> autoFocus() override; Return<Status> cancelAutoFocus() override; Return<Status> takePicture() override; Loading Loading @@ -169,6 +171,16 @@ private: bool mMetadataMode = false; mutable Mutex mBatchLock; // Start of protection scope for mBatchLock uint32_t mBatchSize = 0; // 0 for non-batch mode, set to other value to start batching int32_t mBatchMsgType; // Maybe only allow DataCallbackMsg::VIDEO_FRAME? std::vector<HandleTimestampMessage> mInflightBatch; // End of protection scope for mBatchLock void handleCallbackTimestamp( nsecs_t timestamp, int32_t msg_type, MemoryId memId , unsigned index, native_handle_t* handle); void releaseRecordingFrameLocked(uint32_t memId, uint32_t bufferIndex, const native_handle_t*); // shared memory methods Loading camera/device/1.0/types.hal +33 −0 Original line number Diff line number Diff line Loading @@ -254,3 +254,36 @@ struct CameraFrameMetadata { * between the HAL and the framework. */ typedef uint32_t MemoryId; /* * Struct containing arguments of ICameraDeviceCallback::handleCallbackTimestamp. * Used to send a batch of messages in ICameraDeviceCallback::handleCallbackTimestampBatch. */ struct HandleTimestampMessage { // The handle of image buffer data. handle frameData; // A memory handle to the buffer containing the data MemoryId data; // The offset into the memory handle where the buffer starts. uint32_t bufferIndex; // The time this buffer was captured by the camera, in nanoseconds int64_t timestamp; }; /* * Struct containing arguments of ICameraDevice::releaseRecordingFrameHandle. * Used by camera framework to send a batch of recording frames back to camera HAL. */ struct VideoFrameMessage { // The handle of image buffer data. handle frameData; // A memory handle to the buffer containing the data MemoryId data; // The offset into the memory handle where the buffer starts. uint32_t bufferIndex; }; Loading
camera/device/1.0/ICameraDevice.hal +14 −0 Original line number Diff line number Diff line Loading @@ -327,6 +327,20 @@ interface ICameraDevice { */ releaseRecordingFrameHandle(MemoryId memId, uint32_t bufferIndex, handle frame); /** * Release a batch of record frames previously returned by CAMERA_MSG_VIDEO_FRAME * in handleCallbackTimestampBatch. * * It is camera HAL client's responsibility to release video recording * frames sent out by the camera HAL before the camera HAL receives a call * to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives the call to * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is the camera HAL's * responsibility to manage the life-cycle of the video recording frames. * * @param batch A batch of recording frames to be released by camera HAL. */ releaseRecordingFrameHandleBatch(vec<VideoFrameMessage> batch); /** * Start auto focus. * Loading
camera/device/1.0/ICameraDeviceCallback.hal +16 −2 Original line number Diff line number Diff line Loading @@ -92,10 +92,24 @@ interface ICameraDeviceCallback { * @param timestamp The time this buffer was captured by the camera, in * nanoseconds. * * @return frameId a frame ID to be used with releaseRecordingFrameId later * */ handleCallbackTimestamp(DataCallbackMsg msgType, handle frameData, MemoryId data, uint32_t bufferIndex, int64_t timestamp); /** * Send a batch of image data buffer to the camera service, with timestamps * * This callback can be used to send multiple frames to camera framework in one callback, which * reduce number of callbacks in performance intensive use cases, such as high speed video * recording. The HAL must not mix use of this method with handleCallbackTimestamp in one * recording session (between startRecording and stopRecording) * * @param msgType The kind of image buffer data this call represents. * @param batch a vector messages. Each message contains a image buffer and a timestamp. The * messages must be ordered in time from lower index to higher index, so that timestamp of * i-th message is always smaller than i+1-th message. * */ handleCallbackTimestampBatch(DataCallbackMsg msgType, vec<HandleTimestampMessage> batch); };
camera/device/1.0/default/CameraDevice.cpp +45 −2 Original line number Diff line number Diff line Loading @@ -420,6 +420,39 @@ void CameraDevice::sDataCb(int32_t msg_type, const camera_memory_t *data, unsign } } void CameraDevice::handleCallbackTimestamp( nsecs_t timestamp, int32_t msg_type, MemoryId memId , unsigned index, native_handle_t* handle) { uint32_t batchSize = 0; { Mutex::Autolock _l(mBatchLock); batchSize = mBatchSize; } if (batchSize == 0) { // non-batch mode mDeviceCallback->handleCallbackTimestamp( (DataCallbackMsg) msg_type, handle, memId, index, timestamp); } else { // batch mode Mutex::Autolock _l(mBatchLock); size_t inflightSize = mInflightBatch.size(); if (inflightSize == 0) { mBatchMsgType = msg_type; } else if (mBatchMsgType != msg_type) { ALOGE("%s: msg_type change (from %d to %d) is not supported!", __FUNCTION__, mBatchMsgType, msg_type); return; } mInflightBatch.push_back({handle, memId, index, timestamp}); // Send batched frames to camera framework if (mInflightBatch.size() >= batchSize) { mDeviceCallback->handleCallbackTimestampBatch( (DataCallbackMsg) mBatchMsgType, mInflightBatch); mInflightBatch.clear(); } } } void CameraDevice::sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type, const camera_memory_t *data, unsigned index, void *user) { ALOGV("%s", __FUNCTION__); Loading Loading @@ -450,8 +483,7 @@ void CameraDevice::sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type, object->mDeviceCallback->dataCallbackTimestamp( (DataCallbackMsg) msg_type, mem->handle.mId, index, timestamp); } else { object->mDeviceCallback->handleCallbackTimestamp( (DataCallbackMsg) msg_type, handle, mem->handle.mId, index, timestamp); object->handleCallbackTimestamp(timestamp, msg_type, mem->handle.mId, index, handle); } } } Loading Loading @@ -827,6 +859,17 @@ Return<void> CameraDevice::releaseRecordingFrameHandle( return Void(); } Return<void> CameraDevice::releaseRecordingFrameHandleBatch( const hidl_vec<VideoFrameMessage>& msgs) { ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); Mutex::Autolock _l(mLock); for (auto& msg : msgs) { releaseRecordingFrameLocked( msg.data, msg.bufferIndex, msg.frameData.getNativeHandle()); } return Void(); } Return<Status> CameraDevice::autoFocus() { ALOGV("%s(%s)", __FUNCTION__, mCameraId.c_str()); Mutex::Autolock _l(mLock); Loading
camera/device/1.0/default/CameraDevice_1_0.h +15 −3 Original line number Diff line number Diff line Loading @@ -93,6 +93,8 @@ struct CameraDevice : public ICameraDevice { Return<void> releaseRecordingFrame(uint32_t memId, uint32_t bufferIndex) override; Return<void> releaseRecordingFrameHandle( uint32_t memId, uint32_t bufferIndex, const hidl_handle& frame) override; Return<void> releaseRecordingFrameHandleBatch( const hidl_vec<VideoFrameMessage>&) override; Return<Status> autoFocus() override; Return<Status> cancelAutoFocus() override; Return<Status> takePicture() override; Loading Loading @@ -169,6 +171,16 @@ private: bool mMetadataMode = false; mutable Mutex mBatchLock; // Start of protection scope for mBatchLock uint32_t mBatchSize = 0; // 0 for non-batch mode, set to other value to start batching int32_t mBatchMsgType; // Maybe only allow DataCallbackMsg::VIDEO_FRAME? std::vector<HandleTimestampMessage> mInflightBatch; // End of protection scope for mBatchLock void handleCallbackTimestamp( nsecs_t timestamp, int32_t msg_type, MemoryId memId , unsigned index, native_handle_t* handle); void releaseRecordingFrameLocked(uint32_t memId, uint32_t bufferIndex, const native_handle_t*); // shared memory methods Loading
camera/device/1.0/types.hal +33 −0 Original line number Diff line number Diff line Loading @@ -254,3 +254,36 @@ struct CameraFrameMetadata { * between the HAL and the framework. */ typedef uint32_t MemoryId; /* * Struct containing arguments of ICameraDeviceCallback::handleCallbackTimestamp. * Used to send a batch of messages in ICameraDeviceCallback::handleCallbackTimestampBatch. */ struct HandleTimestampMessage { // The handle of image buffer data. handle frameData; // A memory handle to the buffer containing the data MemoryId data; // The offset into the memory handle where the buffer starts. uint32_t bufferIndex; // The time this buffer was captured by the camera, in nanoseconds int64_t timestamp; }; /* * Struct containing arguments of ICameraDevice::releaseRecordingFrameHandle. * Used by camera framework to send a batch of recording frames back to camera HAL. */ struct VideoFrameMessage { // The handle of image buffer data. handle frameData; // A memory handle to the buffer containing the data MemoryId data; // The offset into the memory handle where the buffer starts. uint32_t bufferIndex; };