Camera: implement buffer managment API
Test: compile
Bug: 109829698
Change-Id: I3d95792282da52db9db6fd6a086bbd7b3ff9dca9
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 2131cf8..1d40d13 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -82,8 +82,6 @@
mLastTemplateId(-1)
{
ATRACE_CALL();
- camera3_callback_ops::notify = &sNotify;
- camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
}
@@ -218,8 +216,17 @@
if (sessionKeysEntry.count > 0) {
sessionParamKeys.insertArrayAt(sessionKeysEntry.data.i32, 0, sessionKeysEntry.count);
}
+
+ camera_metadata_entry bufMgrMode =
+ mDeviceInfo.find(ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION);
+ if (bufMgrMode.count > 0) {
+ mUseHalBufManager = (bufMgrMode.data.u8[0] ==
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
+ }
+
/** Start up request queue thread */
- mRequestThread = new RequestThread(this, mStatusTracker, mInterface, sessionParamKeys);
+ mRequestThread = new RequestThread(
+ this, mStatusTracker, mInterface, sessionParamKeys, mUseHalBufManager);
res = mRequestThread->run(String8::format("C3Dev-%s-ReqQueue", mId.string()).string());
if (res != OK) {
SET_ERR_L("Unable to start request queue thread: %s (%d)",
@@ -271,7 +278,6 @@
return res;
}
}
-
return OK;
}
@@ -919,6 +925,221 @@
return res;
}
+hardware::Return<void> Camera3Device::requestStreamBuffers(
+ const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest>& bufReqs,
+ requestStreamBuffers_cb _hidl_cb) {
+ using hardware::camera::device::V3_5::BufferRequestStatus;
+ using hardware::camera::device::V3_5::StreamBufferRet;
+ using hardware::camera::device::V3_5::StreamBufferRequestError;
+
+ std::lock_guard<std::mutex> lock(mRequestBufferInterfaceLock);
+
+ hardware::hidl_vec<StreamBufferRet> bufRets;
+ if (!mUseHalBufManager) {
+ ALOGE("%s: Camera %s does not support HAL buffer management",
+ __FUNCTION__, mId.string());
+ _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
+ return hardware::Void();
+ }
+
+ SortedVector<int32_t> streamIds;
+ ssize_t sz = streamIds.setCapacity(bufReqs.size());
+ if (sz < 0 || static_cast<size_t>(sz) != bufReqs.size()) {
+ ALOGE("%s: failed to allocate memory for %zu buffer requests",
+ __FUNCTION__, bufReqs.size());
+ _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
+ return hardware::Void();
+ }
+
+ // Check for repeated streamId
+ for (const auto& bufReq : bufReqs) {
+ if (streamIds.indexOf(bufReq.streamId) != NAME_NOT_FOUND) {
+ ALOGE("%s: Stream %d appear multiple times in buffer requests",
+ __FUNCTION__, bufReq.streamId);
+ _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
+ return hardware::Void();
+ }
+ streamIds.add(bufReq.streamId);
+ }
+
+ // TODO: check we are not configuring streams. If so return FAILED_CONFIGURING
+ // Probably need to hook CameraDeviceClient::beginConfigure and figure something
+ // out for API1 client... maybe grab mLock and check mNeedConfig but then we will
+ // need to wait until mLock is released...
+ // _hidl_cb(BufferRequestStatus::FAILED_CONFIGURING, bufRets);
+ // return hardware::Void();
+
+ // TODO: here we start accessing mOutputStreams, might need mLock, but that
+ // might block incoming API calls. Not sure how bad is it.
+ if (bufReqs.size() > mOutputStreams.size()) {
+ ALOGE("%s: too many buffer requests (%zu > # of output streams %zu)",
+ __FUNCTION__, bufReqs.size(), mOutputStreams.size());
+ _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
+ return hardware::Void();
+ }
+
+ bufRets.resize(bufReqs.size());
+
+ bool allReqsSucceeds = true;
+ bool oneReqSucceeds = false;
+ for (size_t i = 0; i < bufReqs.size(); i++) {
+ const auto& bufReq = bufReqs[i];
+ auto& bufRet = bufRets[i];
+ int32_t streamId = bufReq.streamId;
+ ssize_t idx = mOutputStreams.indexOfKey(streamId);
+ if (idx == NAME_NOT_FOUND) {
+ ALOGE("%s: Output stream id %d not found!", __FUNCTION__, streamId);
+ hardware::hidl_vec<StreamBufferRet> emptyBufRets;
+ _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, emptyBufRets);
+ return hardware::Void();
+ }
+ sp<Camera3OutputStreamInterface> outputStream = mOutputStreams.valueAt(idx);
+
+ bufRet.streamId = streamId;
+ uint32_t numBuffersRequested = bufReq.numBuffersRequested;
+ size_t totalHandout = outputStream->getOutstandingBuffersCount() + numBuffersRequested;
+ if (totalHandout > outputStream->asHalStream()->max_buffers) {
+ // Not able to allocate enough buffer. Exit early for this stream
+ bufRet.val.error(StreamBufferRequestError::MAX_BUFFER_EXCEEDED);
+ allReqsSucceeds = false;
+ continue;
+ }
+
+ hardware::hidl_vec<StreamBuffer> tmpRetBuffers(numBuffersRequested);
+ bool currentReqSucceeds = true;
+ std::vector<camera3_stream_buffer_t> streamBuffers(numBuffersRequested);
+ size_t numAllocatedBuffers = 0;
+ size_t numPushedInflightBuffers = 0;
+ for (size_t b = 0; b < numBuffersRequested; b++) {
+ camera3_stream_buffer_t& sb = streamBuffers[b];
+ // Since this method can run concurrently with request thread
+ // We need to update the wait duration everytime we call getbuffer
+ nsecs_t waitDuration = kBaseGetBufferWait + getExpectedInFlightDuration();
+ status_t res = outputStream->getBuffer(&sb, waitDuration);
+ if (res != OK) {
+ ALOGE("%s: Can't get output buffer for stream %d: %s (%d)",
+ __FUNCTION__, streamId, strerror(-res), res);
+ if (res == NO_INIT || res == DEAD_OBJECT) {
+ bufRet.val.error(StreamBufferRequestError::STREAM_DISCONNECTED);
+ } else if (res == TIMED_OUT || res == NO_MEMORY) {
+ bufRet.val.error(StreamBufferRequestError::NO_BUFFER_AVAILABLE);
+ } else {
+ bufRet.val.error(StreamBufferRequestError::UNKNOWN_ERROR);
+ }
+ currentReqSucceeds = false;
+ break;
+ }
+ numAllocatedBuffers++;
+
+ buffer_handle_t *buffer = sb.buffer;
+ auto pair = mInterface->getBufferId(*buffer, streamId);
+ bool isNewBuffer = pair.first;
+ uint64_t bufferId = pair.second;
+ StreamBuffer& hBuf = tmpRetBuffers[b];
+
+ hBuf.streamId = streamId;
+ hBuf.bufferId = bufferId;
+ hBuf.buffer = (isNewBuffer) ? *buffer : nullptr;
+ hBuf.status = BufferStatus::OK;
+ hBuf.releaseFence = nullptr;
+
+ native_handle_t *acquireFence = nullptr;
+ if (sb.acquire_fence != -1) {
+ acquireFence = native_handle_create(1,0);
+ acquireFence->data[0] = sb.acquire_fence;
+ }
+ hBuf.acquireFence.setTo(acquireFence, /*shouldOwn*/true);
+ hBuf.releaseFence = nullptr;
+
+ res = mInterface->pushInflightRequestBuffer(bufferId, buffer);
+ if (res != OK) {
+ ALOGE("%s: Can't get register request buffers for stream %d: %s (%d)",
+ __FUNCTION__, streamId, strerror(-res), res);
+ bufRet.val.error(StreamBufferRequestError::UNKNOWN_ERROR);
+ currentReqSucceeds = false;
+ break;
+ }
+ numPushedInflightBuffers++;
+ }
+ if (currentReqSucceeds) {
+ bufRet.val.buffers(std::move(tmpRetBuffers));
+ oneReqSucceeds = true;
+ } else {
+ allReqsSucceeds = false;
+ for (size_t b = 0; b < numPushedInflightBuffers; b++) {
+ StreamBuffer& hBuf = tmpRetBuffers[b];
+ buffer_handle_t* buffer;
+ status_t res = mInterface->popInflightRequestBuffer(hBuf.bufferId, &buffer);
+ if (res != OK) {
+ SET_ERR("%s: popInflightRequestBuffer failed for stream %d: %s (%d)",
+ __FUNCTION__, streamId, strerror(-res), res);
+ }
+ }
+ returnOutputBuffers(streamBuffers.data(), numAllocatedBuffers, 0);
+ }
+ }
+ // End of mOutputStreams access
+
+ _hidl_cb(allReqsSucceeds ? BufferRequestStatus::OK :
+ oneReqSucceeds ? BufferRequestStatus::FAILED_PARTIAL :
+ BufferRequestStatus::FAILED_UNKNOWN,
+ bufRets);
+ return hardware::Void();
+}
+
+hardware::Return<void> Camera3Device::returnStreamBuffers(
+ const hardware::hidl_vec<hardware::camera::device::V3_2::StreamBuffer>& buffers) {
+ if (!mUseHalBufManager) {
+ ALOGE("%s: Camera %s does not support HAL buffer managerment",
+ __FUNCTION__, mId.string());
+ return hardware::Void();
+ }
+
+ for (const auto& buf : buffers) {
+ if (buf.bufferId == HalInterface::BUFFER_ID_NO_BUFFER) {
+ ALOGE("%s: cannot return a buffer without bufferId", __FUNCTION__);
+ continue;
+ }
+
+ buffer_handle_t* buffer;
+ status_t res = mInterface->popInflightRequestBuffer(buf.bufferId, &buffer);
+
+ if (res != OK) {
+ ALOGE("%s: cannot find in-flight buffer %" PRIu64 " for stream %d",
+ __FUNCTION__, buf.bufferId, buf.streamId);
+ continue;
+ }
+
+ camera3_stream_buffer_t streamBuffer;
+ streamBuffer.buffer = buffer;
+ streamBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
+ streamBuffer.acquire_fence = -1;
+ streamBuffer.release_fence = -1;
+
+ if (buf.releaseFence == nullptr) {
+ streamBuffer.release_fence = -1;
+ } else if (buf.releaseFence->numFds == 1) {
+ streamBuffer.release_fence = dup(buf.releaseFence->data[0]);
+ } else {
+ ALOGE("%s: Invalid release fence, fd count is %d, not 1",
+ __FUNCTION__, buf.releaseFence->numFds);
+ continue;
+ }
+
+ // Need to lock mLock here if we were to allow HAL to return buffer during
+ // stream configuration. This is not currently possible because we only
+ // do stream configuration when there is no inflight buffers in HAL.
+ ssize_t idx = mOutputStreams.indexOfKey(buf.streamId);
+ if (idx == NAME_NOT_FOUND) {
+ ALOGE("%s: Output stream id %d not found!", __FUNCTION__, buf.streamId);
+ continue;
+ }
+ streamBuffer.stream = mOutputStreams.valueAt(idx)->asHalStream();
+ returnOutputBuffers(&streamBuffer, /*size*/1, /*timestamp*/ 0);
+ }
+ return hardware::Void();
+}
+
hardware::Return<void> Camera3Device::processCaptureResult_3_4(
const hardware::hidl_vec<
hardware::camera::device::V3_4::CaptureResult>& results) {
@@ -1076,12 +1297,23 @@
bDst.stream = mOutputStreams.valueAt(idx)->asHalStream();
buffer_handle_t *buffer;
- res = mInterface->popInflightBuffer(result.frameNumber, bSrc.streamId, &buffer);
+ if (mUseHalBufManager) {
+ if (bSrc.bufferId == HalInterface::BUFFER_ID_NO_BUFFER) {
+ ALOGE("%s: Frame %d: Buffer %zu: No bufferId for stream %d",
+ __FUNCTION__, result.frameNumber, i, bSrc.streamId);
+ return;
+ }
+ res = mInterface->popInflightRequestBuffer(bSrc.bufferId, &buffer);
+ } else {
+ res = mInterface->popInflightBuffer(result.frameNumber, bSrc.streamId, &buffer);
+ }
+
if (res != OK) {
ALOGE("%s: Frame %d: Buffer %zu: No in-flight buffer for stream %d",
__FUNCTION__, result.frameNumber, i, bSrc.streamId);
return;
}
+
bDst.buffer = buffer;
bDst.status = mapHidlBufferStatus(bSrc.status);
bDst.acquire_fence = -1;
@@ -3475,6 +3707,10 @@
mRequestMetadataQueue(queue) {
// Check with hardware service manager if we can downcast these interfaces
// Somewhat expensive, so cache the results at startup
+ auto castResult_3_5 = device::V3_5::ICameraDeviceSession::castFrom(mHidlSession);
+ if (castResult_3_5.isOk()) {
+ mHidlSession_3_5 = castResult_3_5;
+ }
auto castResult_3_4 = device::V3_4::ICameraDeviceSession::castFrom(mHidlSession);
if (castResult_3_4.isOk()) {
mHidlSession_3_4 = castResult_3_4;
@@ -4081,6 +4317,33 @@
return OK;
}
+status_t Camera3Device::HalInterface::pushInflightRequestBuffer(
+ uint64_t bufferId, buffer_handle_t* buf) {
+ std::lock_guard<std::mutex> lock(mRequestedBuffersLock);
+ auto pair = mRequestedBuffers.insert({bufferId, buf});
+ if (!pair.second) {
+ ALOGE("%s: bufId %" PRIu64 " is already inflight!",
+ __FUNCTION__, bufferId);
+ return BAD_VALUE;
+ }
+ return OK;
+}
+
+// Find and pop a buffer_handle_t based on bufferId
+status_t Camera3Device::HalInterface::popInflightRequestBuffer(
+ uint64_t bufferId, /*out*/ buffer_handle_t **buffer) {
+ std::lock_guard<std::mutex> lock(mRequestedBuffersLock);
+ auto it = mRequestedBuffers.find(bufferId);
+ if (it == mRequestedBuffers.end()) {
+ ALOGE("%s: bufId %" PRIu64 " is not inflight!",
+ __FUNCTION__, bufferId);
+ return BAD_VALUE;
+ }
+ *buffer = it->second;
+ mRequestedBuffers.erase(it);
+ return OK;
+}
+
std::pair<bool, uint64_t> Camera3Device::HalInterface::getBufferId(
const buffer_handle_t& buf, int streamId) {
std::lock_guard<std::mutex> lock(mBufferIdMapLock);
@@ -4129,7 +4392,8 @@
Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
sp<StatusTracker> statusTracker,
- sp<HalInterface> interface, const Vector<int32_t>& sessionParamKeys) :
+ sp<HalInterface> interface, const Vector<int32_t>& sessionParamKeys,
+ bool useHalBufManager) :
Thread(/*canCallJava*/false),
mParent(parent),
mStatusTracker(statusTracker),
@@ -4149,7 +4413,8 @@
mConstrainedMode(false),
mRequestLatency(kRequestLatencyBinSize),
mSessionParamKeys(sessionParamKeys),
- mLatestSessionParams(sessionParamKeys.size()) {
+ mLatestSessionParams(sessionParamKeys.size()),
+ mUseHalBufManager(useHalBufManager) {
mStatusId = statusTracker->addComponent();
}
@@ -4928,16 +5193,27 @@
}
}
- res = outputStream->getBuffer(&outputBuffers->editItemAt(j),
- waitDuration,
- captureRequest->mOutputSurfaces[outputStream->getId()]);
- if (res != OK) {
- // Can't get output buffer from gralloc queue - this could be due to
- // abandoned queue or other consumer misbehavior, so not a fatal
- // error
- ALOGE("RequestThread: Can't get output buffer, skipping request:"
- " %s (%d)", strerror(-res), res);
- return TIMED_OUT;
+ if (mUseHalBufManager) {
+ // HAL will request buffer through requestStreamBuffer API
+ camera3_stream_buffer_t& buffer = outputBuffers->editItemAt(j);
+ buffer.stream = outputStream->asHalStream();
+ buffer.buffer = nullptr;
+ buffer.status = CAMERA3_BUFFER_STATUS_OK;
+ buffer.acquire_fence = -1;
+ buffer.release_fence = -1;
+ } else {
+ res = outputStream->getBuffer(&outputBuffers->editItemAt(j),
+ waitDuration,
+ captureRequest->mOutputSurfaces[outputStream->getId()]);
+ if (res != OK) {
+ // Can't get output buffer from gralloc queue - this could be due to
+ // abandoned queue or other consumer misbehavior, so not a fatal
+ // error
+ ALOGE("RequestThread: Can't get output buffer, skipping request:"
+ " %s (%d)", strerror(-res), res);
+
+ return TIMED_OUT;
+ }
}
String8 physicalCameraId = outputStream->getPhysicalCameraId();
@@ -5794,23 +6070,4 @@
return true;
}
-/**
- * Static callback forwarding methods from HAL to instance
- */
-
-void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
- const camera3_capture_result *result) {
- Camera3Device *d =
- const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
-
- d->processCaptureResult(result);
-}
-
-void Camera3Device::sNotify(const camera3_callback_ops *cb,
- const camera3_notify_msg *msg) {
- Camera3Device *d =
- const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
- d->notify(msg);
-}
-
}; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 5e749b6..7656ef3 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -33,10 +33,11 @@
#include <android/hardware/camera/device/3.2/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.3/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
+#include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.2/ICameraDeviceCallback.h>
#include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h>
+#include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
#include <fmq/MessageQueue.h>
-#include <hardware/camera3.h>
#include <camera/CaptureResult.h>
@@ -50,20 +51,6 @@
using android::camera3::OutputStreamInfo;
-/**
- * Function pointer types with C calling convention to
- * use for HAL callback functions.
- */
-extern "C" {
- typedef void (callbacks_process_capture_result_t)(
- const struct camera3_callback_ops *,
- const camera3_capture_result_t *);
-
- typedef void (callbacks_notify_t)(
- const struct camera3_callback_ops *,
- const camera3_notify_msg_t *);
-}
-
namespace android {
namespace camera3 {
@@ -80,8 +67,7 @@
*/
class Camera3Device :
public CameraDeviceBase,
- virtual public hardware::camera::device::V3_4::ICameraDeviceCallback,
- private camera3_callback_ops {
+ virtual public hardware::camera::device::V3_5::ICameraDeviceCallback {
public:
explicit Camera3Device(const String8& id);
@@ -299,14 +285,25 @@
status_t dump(int fd);
status_t close();
+ // method to extract buffer's unique ID
+ // return pair of (newlySeenBuffer?, bufferId)
+ std::pair<bool, uint64_t> getBufferId(const buffer_handle_t& buf, int streamId);
+
// Find a buffer_handle_t based on frame number and stream ID
status_t popInflightBuffer(int32_t frameNumber, int32_t streamId,
/*out*/ buffer_handle_t **buffer);
+ // Register a bufId/buffer_handle_t to inflight request buffer
+ status_t pushInflightRequestBuffer(uint64_t bufferId, buffer_handle_t* buf);
+
+ // Find a buffer_handle_t based on bufferId
+ status_t popInflightRequestBuffer(uint64_t bufferId, /*out*/ buffer_handle_t **buffer);
+
// Get a vector of (frameNumber, streamId) pair of currently inflight
// buffers
void getInflightBufferKeys(std::vector<std::pair<int32_t, int32_t>>* out);
+ static const uint64_t BUFFER_ID_NO_BUFFER = 0;
private:
// Always valid
sp<hardware::camera::device::V3_2::ICameraDeviceSession> mHidlSession;
@@ -314,6 +311,8 @@
sp<hardware::camera::device::V3_3::ICameraDeviceSession> mHidlSession_3_3;
// Valid if ICameraDeviceSession is @3.4 or newer
sp<hardware::camera::device::V3_4::ICameraDeviceSession> mHidlSession_3_4;
+ // Valid if ICameraDeviceSession is @3.5 or newer
+ sp<hardware::camera::device::V3_5::ICameraDeviceSession> mHidlSession_3_5;
std::shared_ptr<RequestMetadataQueue> mRequestMetadataQueue;
@@ -365,19 +364,14 @@
// stream ID -> per stream buffer ID map
std::unordered_map<int, BufferIdMap> mBufferIdMaps;
uint64_t mNextBufferId = 1; // 0 means no buffer
- static const uint64_t BUFFER_ID_NO_BUFFER = 0;
-
- // method to extract buffer's unique ID
- // TODO: we should switch to use gralloc mapper's getBackingStore API
- // once we ran in binderized gralloc mode, but before that is ready,
- // we need to rely on the conventional buffer queue behavior where
- // buffer_handle_t's FD won't change.
- // return pair of (newlySeenBuffer?, bufferId)
- std::pair<bool, uint64_t> getBufferId(const buffer_handle_t& buf, int streamId);
virtual void onBufferFreed(int streamId, const native_handle_t* handle) override;
std::vector<std::pair<int, uint64_t>> mFreedBuffers;
+
+ // Buffers given to HAL through requestStreamBuffer API
+ std::mutex mRequestedBuffersLock;
+ std::unordered_map<uint64_t, buffer_handle_t*> mRequestedBuffers;
};
sp<HalInterface> mInterface;
@@ -483,8 +477,9 @@
/**
- * Implementation of android::hardware::camera::device::V3_4::ICameraDeviceCallback
+ * Implementation of android::hardware::camera::device::V3_5::ICameraDeviceCallback
*/
+
hardware::Return<void> processCaptureResult_3_4(
const hardware::hidl_vec<
hardware::camera::device::V3_4::CaptureResult>& results) override;
@@ -495,6 +490,15 @@
const hardware::hidl_vec<
hardware::camera::device::V3_2::NotifyMsg>& msgs) override;
+ hardware::Return<void> requestStreamBuffers(
+ const hardware::hidl_vec<
+ hardware::camera::device::V3_5::BufferRequest>& bufReqs,
+ requestStreamBuffers_cb _hidl_cb) override;
+
+ hardware::Return<void> returnStreamBuffers(
+ const hardware::hidl_vec<
+ hardware::camera::device::V3_2::StreamBuffer>& buffers) override;
+
// Handle one capture result. Assume that mProcessCaptureResultLock is held.
void processOneCaptureResultLocked(
const hardware::camera::device::V3_2::CaptureResult& result,
@@ -702,7 +706,9 @@
RequestThread(wp<Camera3Device> parent,
sp<camera3::StatusTracker> statusTracker,
- sp<HalInterface> interface, const Vector<int32_t>& sessionParamKeys);
+ sp<HalInterface> interface,
+ const Vector<int32_t>& sessionParamKeys,
+ bool useHalBufManager);
~RequestThread();
void setNotificationListener(wp<NotificationListener> listener);
@@ -937,6 +943,8 @@
Vector<int32_t> mSessionParamKeys;
CameraMetadata mLatestSessionParams;
+
+ const bool mUseHalBufManager;
};
sp<RequestThread> mRequestThread;
@@ -1020,7 +1028,7 @@
InFlightRequest(int numBuffers, CaptureResultExtras extras, bool hasInput,
bool hasAppCallback, nsecs_t maxDuration,
- const std::set<String8>& physicalCameraIdSet, bool isStillCapture,
+ const std::set<String8>& physicalCameraIdSet, bool isStillCapture,
bool isZslCapture) :
shutterTimestamp(0),
sensorTimestamp(0),
@@ -1217,16 +1225,16 @@
// Cached last requested template id
int mLastTemplateId;
- /**
- * Static callback forwarding methods from HAL to instance
- */
- static callbacks_process_capture_result_t sProcessCaptureResult;
-
- static callbacks_notify_t sNotify;
-
// Synchronizes access to status tracker between inflight updates and disconnect.
// b/79972865
Mutex mTrackerLock;
+
+ // Whether HAL request buffers through requestStreamBuffer API
+ bool mUseHalBufManager = false;
+
+ // Lock to ensure requestStreamBuffers() callbacks are serialized
+ std::mutex mRequestBufferInterfaceLock;
+
}; // class Camera3Device
}; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index 3c1e43d..18b8c4d 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -116,7 +116,7 @@
return mTotalBufferCount;
}
-size_t Camera3IOStreamBase::getHandoutOutputBufferCountLocked() {
+size_t Camera3IOStreamBase::getHandoutOutputBufferCountLocked() const {
return mHandoutOutputBufferCount;
}
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
index 0a31d44..48e9bbf 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
@@ -82,7 +82,7 @@
virtual size_t getBufferCountLocked();
- virtual size_t getHandoutOutputBufferCountLocked();
+ virtual size_t getHandoutOutputBufferCountLocked() const;
virtual size_t getHandoutInputBufferCountLocked();
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
index fb3ce4c..1c13950 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
@@ -138,6 +138,10 @@
return res;
}
+ // TODO: need to refactor this to support requestStreamBuffers API
+ // Need to wait until processCaptureResult to decide the source buffer
+ // to attach to output...
+
// Attach the buffer to the splitter output queues. This could block if
// the output queue doesn't have any empty slot. So unlock during the course
// of attachBufferToOutputs.
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index ee989e1..0a30a97 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -795,6 +795,12 @@
return hasOutstandingBuffersLocked();
}
+size_t Camera3Stream::getOutstandingBuffersCount() const {
+ ATRACE_CALL();
+ Mutex::Autolock l(mLock);
+ return getHandoutOutputBufferCountLocked();
+}
+
status_t Camera3Stream::setStatusTracker(sp<StatusTracker> statusTracker) {
Mutex::Autolock l(mLock);
sp<StatusTracker> oldTracker = mStatusTracker.promote();
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index 1c67fb2..e29c3e0 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -360,6 +360,11 @@
*/
bool hasOutstandingBuffers() const;
+ /**
+ * Get number of buffers currently handed out to HAL
+ */
+ size_t getOutstandingBuffersCount() const;
+
enum {
TIMEOUT_NEVER = -1
};
@@ -495,7 +500,7 @@
virtual size_t getBufferCountLocked() = 0;
// Get handout output buffer count.
- virtual size_t getHandoutOutputBufferCountLocked() = 0;
+ virtual size_t getHandoutOutputBufferCountLocked() const = 0;
// Get handout input buffer count.
virtual size_t getHandoutInputBufferCountLocked() = 0;
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index 5758ac8..866b722 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -289,6 +289,11 @@
*/
virtual bool hasOutstandingBuffers() const = 0;
+ /**
+ * Get number of buffers currently handed out to HAL
+ */
+ virtual size_t getOutstandingBuffersCount() const = 0;
+
enum {
TIMEOUT_NEVER = -1
};