Use fmq for camera capture request.

Test: camera works.

Bug: 35788245 [Treble] Pass camera metadata using shared memory
Change-Id: I4a1585315bf448c8c57def2964237cae21bdbe03
This commit is contained in:
Yifan Hong 2017-04-11 14:45:00 -07:00
parent e7375c079d
commit 1192e1d109
7 changed files with 91 additions and 18 deletions

View file

@ -167,7 +167,7 @@ interface ICameraDevice {
* longer available. This interface is now stale, and a new instance * longer available. This interface is now stale, and a new instance
* must be acquired if the device is reconnected. All subsequent * must be acquired if the device is reconnected. All subsequent
* calls on this interface must return CAMERA_DISCONNECTED. * calls on this interface must return CAMERA_DISCONNECTED.
* @return cameraDevice The interface to the newly-opened camera session, * @return session The interface to the newly-opened camera session,
* or null if status is not OK. * or null if status is not OK.
*/ */
open(ICameraDeviceCallback callback) generates open(ICameraDeviceCallback callback) generates

View file

@ -247,6 +247,21 @@ interface ICameraDeviceSession {
vec<BufferCache> cachesToRemove) vec<BufferCache> cachesToRemove)
generates (Status status, uint32_t numRequestProcessed); generates (Status status, uint32_t numRequestProcessed);
/**
* getCaptureRequestMetadataQueue:
*
* Retrieves the queue used along with processCaptureRequest. If
* client decides to use fast message queue to pass request metadata,
* it must:
* - Call getCaptureRequestMetadataQueue to retrieve the fast message queue;
* - In each of the requests sent in processCaptureRequest, set
* fmqSettingsSize field of CaptureRequest to be the size to read from the
* fast message queue; leave settings field of CaptureRequest empty.
*
* @return queue the queue that client writes request metadata to.
*/
getCaptureRequestMetadataQueue() generates (fmq_sync<uint8_t> queue);
/** /**
* flush: * flush:
* *

View file

@ -14,10 +14,14 @@ cc_library_shared {
"android.hardware.camera.provider@2.4", "android.hardware.camera.provider@2.4",
"liblog", "liblog",
"libhardware", "libhardware",
"libcamera_metadata" "libcamera_metadata",
"libfmq"
], ],
static_libs: [ static_libs: [
"android.hardware.camera.common@1.0-helper" "android.hardware.camera.common@1.0-helper"
], ],
export_include_dirs: ["."] export_include_dirs: ["."],
export_shared_lib_headers: [
"libfmq",
]
} }

View file

@ -30,6 +30,9 @@ namespace device {
namespace V3_2 { namespace V3_2 {
namespace implementation { namespace implementation {
// Size of request metadata fast message queue. Change to 0 to always use hwbinder buffer.
static constexpr size_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */;
HandleImporter& CameraDeviceSession::sHandleImporter = HandleImporter::getInstance(); HandleImporter& CameraDeviceSession::sHandleImporter = HandleImporter::getInstance();
const int CameraDeviceSession::ResultBatcher::NOT_BATCHED; const int CameraDeviceSession::ResultBatcher::NOT_BATCHED;
@ -66,6 +69,14 @@ bool CameraDeviceSession::initialize() {
mClosed = true; mClosed = true;
return true; return true;
} }
mRequestMetadataQueue = std::make_unique<RequestMetadataQueue>(
CAMERA_REQUEST_METADATA_QUEUE_SIZE, false /* non blocking */);
if (!mRequestMetadataQueue->isValid()) {
ALOGE("%s: invalid fmq", __FUNCTION__);
return true;
}
return false; return false;
} }
@ -699,6 +710,12 @@ void CameraDeviceSession::updateBufferCaches(const hidl_vec<BufferCache>& caches
} }
} }
Return<void> CameraDeviceSession::getCaptureRequestMetadataQueue(
getCaptureRequestMetadataQueue_cb _hidl_cb) {
_hidl_cb(*mRequestMetadataQueue->getDesc());
return Void();
}
Return<void> CameraDeviceSession::processCaptureRequest( Return<void> CameraDeviceSession::processCaptureRequest(
const hidl_vec<CaptureRequest>& requests, const hidl_vec<CaptureRequest>& requests,
const hidl_vec<BufferCache>& cachesToRemove, const hidl_vec<BufferCache>& cachesToRemove,
@ -731,7 +748,24 @@ Status CameraDeviceSession::processOneCaptureRequest(const CaptureRequest& reque
camera3_capture_request_t halRequest; camera3_capture_request_t halRequest;
halRequest.frame_number = request.frameNumber; halRequest.frame_number = request.frameNumber;
bool converted = convertFromHidl(request.settings, &halRequest.settings);
bool converted = true;
CameraMetadata settingsFmq; // settings from FMQ
if (request.fmqSettingsSize > 0) {
// non-blocking read; client must write metadata before calling
// processOneCaptureRequest
settingsFmq.resize(request.fmqSettingsSize);
bool read = mRequestMetadataQueue->read(settingsFmq.data(), request.fmqSettingsSize);
if (read) {
converted = convertFromHidl(settingsFmq, &halRequest.settings);
} else {
ALOGE("%s: capture request settings metadata couldn't be read from fmq!", __FUNCTION__);
converted = false;
}
} else {
converted = convertFromHidl(request.settings, &halRequest.settings);
}
if (!converted) { if (!converted) {
ALOGE("%s: capture request settings metadata is corrupt!", __FUNCTION__); ALOGE("%s: capture request settings metadata is corrupt!", __FUNCTION__);
return Status::INTERNAL_ERROR; return Status::INTERNAL_ERROR;

View file

@ -17,19 +17,20 @@
#ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H #ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
#define ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H #define ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
#include <android/hardware/camera/device/3.2/ICameraDevice.h>
#include <android/hardware/camera/device/3.2/ICameraDeviceSession.h>
#include <fmq/MessageQueue.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <include/convert.h>
#include <deque> #include <deque>
#include <map> #include <map>
#include <unordered_map> #include <unordered_map>
#include "hardware/camera_common.h"
#include "hardware/camera3.h"
#include "utils/Mutex.h"
#include <android/hardware/camera/device/3.2/ICameraDevice.h>
#include <android/hardware/camera/device/3.2/ICameraDeviceSession.h>
#include <hidl/Status.h>
#include <hidl/MQDescriptor.h>
#include <include/convert.h>
#include "HandleImporter.h"
#include "CameraMetadata.h" #include "CameraMetadata.h"
#include "HandleImporter.h"
#include "hardware/camera3.h"
#include "hardware/camera_common.h"
#include "utils/Mutex.h"
namespace android { namespace android {
namespace hardware { namespace hardware {
@ -44,6 +45,9 @@ using ::android::hardware::camera::device::V3_2::StreamConfiguration;
using ::android::hardware::camera::device::V3_2::ICameraDeviceSession; using ::android::hardware::camera::device::V3_2::ICameraDeviceSession;
using ::android::hardware::camera::common::V1_0::Status; using ::android::hardware::camera::common::V1_0::Status;
using ::android::hardware::camera::common::V1_0::helper::HandleImporter; using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
using ::android::hardware::kSynchronizedReadWrite;
using ::android::hardware::MessageQueue;
using ::android::hardware::MQDescriptorSync;
using ::android::hardware::Return; using ::android::hardware::Return;
using ::android::hardware::Void; using ::android::hardware::Void;
using ::android::hardware::hidl_vec; using ::android::hardware::hidl_vec;
@ -84,6 +88,8 @@ struct CameraDeviceSession : public ICameraDeviceSession, private camera3_callba
RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) override; RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) override;
Return<void> configureStreams( Return<void> configureStreams(
const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override; const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override;
Return<void> getCaptureRequestMetadataQueue(
getCaptureRequestMetadataQueue_cb _hidl_cb) override;
Return<void> processCaptureRequest( Return<void> processCaptureRequest(
const hidl_vec<CaptureRequest>& requests, const hidl_vec<CaptureRequest>& requests,
const hidl_vec<BufferCache>& cachesToRemove, const hidl_vec<BufferCache>& cachesToRemove,
@ -126,6 +132,9 @@ private:
common::V1_0::helper::CameraMetadata mDeviceInfo; common::V1_0::helper::CameraMetadata mDeviceInfo;
using RequestMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
std::unique_ptr<RequestMetadataQueue> mRequestMetadataQueue;
class ResultBatcher { class ResultBatcher {
public: public:
ResultBatcher(const sp<ICameraDeviceCallback>& callback); ResultBatcher(const sp<ICameraDeviceCallback>& callback);

View file

@ -753,11 +753,22 @@ struct CaptureRequest {
uint32_t frameNumber; uint32_t frameNumber;
/** /**
* The settings buffer contains the capture and processing parameters for * If non-zero, read settings from request queue instead
* (see ICameraDeviceSession.getCaptureRequestMetadataQueue).
* If zero, read settings from .settings field.
*/
uint64_t fmqSettingsSize;
/**
* If fmqSettingsSize is zero,
* the settings buffer contains the capture and processing parameters for
* the request. As a special case, an empty settings buffer indicates that * the request. As a special case, an empty settings buffer indicates that
* the settings are identical to the most-recently submitted capture * the settings are identical to the most-recently submitted capture
* request. A empty buffer cannot be used as the first submitted request * request. A empty buffer cannot be used as the first submitted request
* after a configureStreams() call. * after a configureStreams() call.
*
* This field must be used if fmqSettingsSize is zero. It must not be used
* if fmqSettingsSize is non-zero.
*/ */
CameraMetadata settings; CameraMetadata settings;

View file

@ -2493,7 +2493,7 @@ TEST_F(CameraHidlTest, processCaptureRequestPreview) {
outputBuffer}; outputBuffer};
StreamBuffer emptyInputBuffer = {-1, 0, nullptr, StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
BufferStatus::ERROR, nullptr, nullptr}; BufferStatus::ERROR, nullptr, nullptr};
CaptureRequest request = {frameNumber, settings, CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
emptyInputBuffer, outputBuffers}; emptyInputBuffer, outputBuffers};
{ {
@ -2599,7 +2599,7 @@ TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) {
outputBuffer}; outputBuffer};
StreamBuffer emptyInputBuffer = {-1, 0, nullptr, StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
BufferStatus::ERROR, nullptr, nullptr}; BufferStatus::ERROR, nullptr, nullptr};
CaptureRequest request = {frameNumber, settings, CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
emptyInputBuffer, outputBuffers}; emptyInputBuffer, outputBuffers};
//Settings were not correctly initialized, we should fail here //Settings were not correctly initialized, we should fail here
@ -2654,7 +2654,7 @@ TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) {
::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers; ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers;
StreamBuffer emptyInputBuffer = {-1, 0, nullptr, StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
BufferStatus::ERROR, nullptr, nullptr}; BufferStatus::ERROR, nullptr, nullptr};
CaptureRequest request = {frameNumber, settings, CaptureRequest request = {frameNumber, 0/* fmqSettingsSize */, settings,
emptyInputBuffer, emptyOutputBuffers}; emptyInputBuffer, emptyOutputBuffers};
//Output buffers are missing, we should fail here //Output buffers are missing, we should fail here
@ -2719,7 +2719,7 @@ TEST_F(CameraHidlTest, flushPreviewRequest) {
outputBuffer}; outputBuffer};
const StreamBuffer emptyInputBuffer = {-1, 0, nullptr, const StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
BufferStatus::ERROR, nullptr, nullptr}; BufferStatus::ERROR, nullptr, nullptr};
CaptureRequest request = {frameNumber, settings, CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
emptyInputBuffer, outputBuffers}; emptyInputBuffer, outputBuffers};
{ {