Merge "Use fmq for camera capture request." into oc-dev
am: 84deaeb4f9
Change-Id: Iabc1d68e52ac99a96013558f764d23219d26a9f0
This commit is contained in:
commit
bb43d5e297
7 changed files with 91 additions and 18 deletions
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
*
|
*
|
||||||
|
|
|
@ -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",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue