Add v2 onCaptureStartedCallback: adds frame number to callback.
Bug: 214261327
Test: camera CTS native tests
Test: ACameraNdkVendorTest
Change-Id: I1b249a9b16cc9256a1604aacde6baa25b3b01fcb
Signed-off-by: Jayant Chowdhary <jchowdhary@google.com>
diff --git a/camera/ndk/NdkCameraCaptureSession.cpp b/camera/ndk/NdkCameraCaptureSession.cpp
index 1ac8482..9c98778 100644
--- a/camera/ndk/NdkCameraCaptureSession.cpp
+++ b/camera/ndk/NdkCameraCaptureSession.cpp
@@ -29,6 +29,7 @@
#include "impl/ACameraCaptureSession.h"
#include "impl/ACameraCaptureSession.inc"
+#include "NdkCameraCaptureSession.inc"
using namespace android;
@@ -72,22 +73,16 @@
int numRequests, ACaptureRequest** requests,
/*optional*/int* captureSequenceId) {
ATRACE_CALL();
- if (session == nullptr || requests == nullptr || numRequests < 1) {
- ALOGE("%s: Error: invalid input: session %p, numRequest %d, requests %p",
- __FUNCTION__, session, numRequests, requests);
- return ACAMERA_ERROR_INVALID_PARAMETER;
- }
+ return captureTemplate(session, cbs, numRequests, requests, captureSequenceId);
+}
- if (session->isClosed()) {
- ALOGE("%s: session %p is already closed", __FUNCTION__, session);
- if (captureSequenceId != nullptr) {
- *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
- }
- return ACAMERA_ERROR_SESSION_CLOSED;
- }
-
- return session->capture(
- cbs, numRequests, requests, captureSequenceId);
+EXPORT
+camera_status_t ACameraCaptureSession_captureV2(
+ ACameraCaptureSession* session, /*optional*/ACameraCaptureSession_captureCallbacksV2* cbs,
+ int numRequests, ACaptureRequest** requests,
+ /*optional*/int* captureSequenceId) {
+ ATRACE_CALL();
+ return captureTemplate(session, cbs, numRequests, requests, captureSequenceId);
}
EXPORT
@@ -97,22 +92,26 @@
int numRequests, ACaptureRequest** requests,
/*optional*/int* captureSequenceId) {
ATRACE_CALL();
- if (session == nullptr || requests == nullptr || numRequests < 1) {
- ALOGE("%s: Error: invalid input: session %p, numRequest %d, requests %p",
- __FUNCTION__, session, numRequests, requests);
- return ACAMERA_ERROR_INVALID_PARAMETER;
- }
+ return captureTemplate(session, lcbs, numRequests, requests, captureSequenceId);
+}
- if (session->isClosed()) {
- ALOGE("%s: session %p is already closed", __FUNCTION__, session);
- if (captureSequenceId) {
- *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
- }
- return ACAMERA_ERROR_SESSION_CLOSED;
- }
+EXPORT
+camera_status_t ACameraCaptureSession_logicalCamera_captureV2(
+ ACameraCaptureSession* session,
+ /*optional*/ACameraCaptureSession_logicalCamera_captureCallbacksV2* lcbs,
+ int numRequests, ACaptureRequest** requests,
+ /*optional*/int* captureSequenceId) {
+ ATRACE_CALL();
+ return captureTemplate(session, lcbs, numRequests, requests, captureSequenceId);
+}
- return session->capture(
- lcbs, numRequests, requests, captureSequenceId);
+EXPORT
+camera_status_t ACameraCaptureSession_setRepeatingRequestV2(
+ ACameraCaptureSession* session, /*optional*/ACameraCaptureSession_captureCallbacksV2* cbs,
+ int numRequests, ACaptureRequest** requests,
+ /*optional*/int* captureSequenceId) {
+ ATRACE_CALL();
+ return setRepeatingRequestTemplate(session, cbs, numRequests, requests, captureSequenceId);
}
EXPORT
@@ -121,23 +120,10 @@
int numRequests, ACaptureRequest** requests,
/*optional*/int* captureSequenceId) {
ATRACE_CALL();
- if (session == nullptr || requests == nullptr || numRequests < 1) {
- ALOGE("%s: Error: invalid input: session %p, numRequest %d, requests %p",
- __FUNCTION__, session, numRequests, requests);
- return ACAMERA_ERROR_INVALID_PARAMETER;
- }
-
- if (session->isClosed()) {
- ALOGE("%s: session %p is already closed", __FUNCTION__, session);
- if (captureSequenceId) {
- *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
- }
- return ACAMERA_ERROR_SESSION_CLOSED;
- }
-
- return session->setRepeatingRequest(cbs, numRequests, requests, captureSequenceId);
+ return setRepeatingRequestTemplate(session, cbs, numRequests, requests, captureSequenceId);
}
+
EXPORT
camera_status_t ACameraCaptureSession_logicalCamera_setRepeatingRequest(
ACameraCaptureSession* session,
@@ -145,21 +131,18 @@
int numRequests, ACaptureRequest** requests,
/*optional*/int* captureSequenceId) {
ATRACE_CALL();
- if (session == nullptr || requests == nullptr || numRequests < 1) {
- ALOGE("%s: Error: invalid input: session %p, numRequest %d, requests %p",
- __FUNCTION__, session, numRequests, requests);
- return ACAMERA_ERROR_INVALID_PARAMETER;
- }
+ return setRepeatingRequestTemplate(session, lcbs, numRequests, requests, captureSequenceId);
+}
- if (session->isClosed()) {
- ALOGE("%s: session %p is already closed", __FUNCTION__, session);
- if (captureSequenceId) {
- *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
- }
- return ACAMERA_ERROR_SESSION_CLOSED;
- }
- return session->setRepeatingRequest(lcbs, numRequests, requests, captureSequenceId);
+EXPORT
+camera_status_t ACameraCaptureSession_logicalCamera_setRepeatingRequestV2(
+ ACameraCaptureSession* session,
+ /*optional*/ACameraCaptureSession_logicalCamera_captureCallbacksV2* lcbs,
+ int numRequests, ACaptureRequest** requests,
+ /*optional*/int* captureSequenceId) {
+ ATRACE_CALL();
+ return setRepeatingRequestTemplate(session, lcbs, numRequests, requests, captureSequenceId);
}
EXPORT
diff --git a/camera/ndk/NdkCameraCaptureSession.inc b/camera/ndk/NdkCameraCaptureSession.inc
new file mode 100644
index 0000000..258e20d
--- /dev/null
+++ b/camera/ndk/NdkCameraCaptureSession.inc
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "impl/ACameraCaptureSession.h"
+
+#include <camera/NdkCameraCaptureSession.h>
+
+using namespace android;
+
+template <class CallbackType>
+camera_status_t captureTemplate(
+ ACameraCaptureSession* session,
+ /*optional*/CallbackType* cbs,
+ int numRequests, ACaptureRequest** requests,
+ /*optional*/int* captureSequenceId) {
+ ATRACE_CALL();
+ if (session == nullptr || requests == nullptr || numRequests < 1) {
+ ALOGE("%s: Error: invalid input: session %p, numRequest %d, requests %p",
+ __FUNCTION__, session, numRequests, requests);
+ return ACAMERA_ERROR_INVALID_PARAMETER;
+ }
+
+ if (session->isClosed()) {
+ ALOGE("%s: session %p is already closed", __FUNCTION__, session);
+ if (captureSequenceId) {
+ *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+ }
+ return ACAMERA_ERROR_SESSION_CLOSED;
+ }
+
+ return session->capture(
+ cbs, numRequests, requests, captureSequenceId);
+}
+
+template <class CallbackType>
+camera_status_t setRepeatingRequestTemplate(
+ ACameraCaptureSession* session,
+ /*optional*/CallbackType* cbs,
+ int numRequests, ACaptureRequest** requests,
+ /*optional*/int* captureSequenceId) {
+ ATRACE_CALL();
+ if (session == nullptr || requests == nullptr || numRequests < 1) {
+ ALOGE("%s: Error: invalid input: session %p, numRequest %d, requests %p",
+ __FUNCTION__, session, numRequests, requests);
+ return ACAMERA_ERROR_INVALID_PARAMETER;
+ }
+
+ if (session->isClosed()) {
+ ALOGE("%s: session %p is already closed", __FUNCTION__, session);
+ if (captureSequenceId) {
+ *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+ }
+ return ACAMERA_ERROR_SESSION_CLOSED;
+ }
+
+ return session->setRepeatingRequest(cbs, numRequests, requests, captureSequenceId);
+}
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index dd652c7..7997768 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -26,8 +26,6 @@
#include "ACaptureRequest.h"
#include "ACameraCaptureSession.h"
-#include "ACameraCaptureSession.inc"
-
ACameraDevice::~ACameraDevice() {
mDevice->stopLooperAndDisconnect();
}
@@ -913,6 +911,7 @@
case kWhatOnError:
case kWhatSessionStateCb:
case kWhatCaptureStart:
+ case kWhatCaptureStart2:
case kWhatCaptureResult:
case kWhatLogicalCaptureResult:
case kWhatCaptureFail:
@@ -985,6 +984,7 @@
}
case kWhatSessionStateCb:
case kWhatCaptureStart:
+ case kWhatCaptureStart2:
case kWhatCaptureResult:
case kWhatLogicalCaptureResult:
case kWhatCaptureFail:
@@ -1004,6 +1004,7 @@
sp<CaptureRequest> requestSp = nullptr;
switch (msg->what()) {
case kWhatCaptureStart:
+ case kWhatCaptureStart2:
case kWhatCaptureResult:
case kWhatLogicalCaptureResult:
case kWhatCaptureFail:
@@ -1055,6 +1056,35 @@
freeACaptureRequest(request);
break;
}
+ case kWhatCaptureStart2:
+ {
+ ACameraCaptureSession_captureCallback_startV2 onStart2;
+ found = msg->findPointer(kCallbackFpKey, (void**) &onStart2);
+ if (!found) {
+ ALOGE("%s: Cannot find capture startV2 callback!", __FUNCTION__);
+ return;
+ }
+ if (onStart2 == nullptr) {
+ return;
+ }
+ int64_t timestamp;
+ found = msg->findInt64(kTimeStampKey, ×tamp);
+ if (!found) {
+ ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
+ return;
+ }
+ int64_t frameNumber;
+ found = msg->findInt64(kFrameNumberKey, &frameNumber);
+ if (!found) {
+ ALOGE("%s: Cannot find frame number!", __FUNCTION__);
+ return;
+ }
+
+ ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
+ (*onStart2)(context, session.get(), request, timestamp, frameNumber);
+ freeACaptureRequest(request);
+ break;
+ }
case kWhatCaptureResult:
{
ACameraCaptureSession_captureCallback_result onResult;
@@ -1285,7 +1315,8 @@
ACameraCaptureSession_captureCallbacks* cbs) :
mSession(session), mRequests(requests),
mIsRepeating(isRepeating),
- mIsLogicalCameraCallback(false) {
+ mIsLogicalCameraCallback(false),
+ mIs2Callback(false) {
initCaptureCallbacks(cbs);
if (cbs != nullptr) {
@@ -1301,7 +1332,8 @@
ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
mSession(session), mRequests(requests),
mIsRepeating(isRepeating),
- mIsLogicalCameraCallback(true) {
+ mIsLogicalCameraCallback(true),
+ mIs2Callback(false) {
initCaptureCallbacks(lcbs);
if (lcbs != nullptr) {
@@ -1310,6 +1342,40 @@
}
}
+CameraDevice::CallbackHolder::CallbackHolder(
+ sp<ACameraCaptureSession> session,
+ const Vector<sp<CaptureRequest> >& requests,
+ bool isRepeating,
+ ACameraCaptureSession_captureCallbacksV2* cbs) :
+ mSession(session), mRequests(requests),
+ mIsRepeating(isRepeating),
+ mIsLogicalCameraCallback(false),
+ mIs2Callback(true) {
+ initCaptureCallbacksV2(cbs);
+
+ if (cbs != nullptr) {
+ mOnCaptureCompleted = cbs->onCaptureCompleted;
+ mOnCaptureFailed = cbs->onCaptureFailed;
+ }
+}
+
+CameraDevice::CallbackHolder::CallbackHolder(
+ sp<ACameraCaptureSession> session,
+ const Vector<sp<CaptureRequest> >& requests,
+ bool isRepeating,
+ ACameraCaptureSession_logicalCamera_captureCallbacksV2* lcbs) :
+ mSession(session), mRequests(requests),
+ mIsRepeating(isRepeating),
+ mIsLogicalCameraCallback(true),
+ mIs2Callback(true) {
+ initCaptureCallbacksV2(lcbs);
+
+ if (lcbs != nullptr) {
+ mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
+ mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
+ }
+}
+
void
CameraDevice::checkRepeatingSequenceCompleteLocked(
const int sequenceId, const int64_t lastFrameNumber) {
@@ -1536,7 +1602,6 @@
const CaptureResultExtras& resultExtras,
int64_t timestamp) {
binder::Status ret = binder::Status::ok();
-
sp<CameraDevice> dev = mDevice.promote();
if (dev == nullptr) {
return ret; // device has been closed
@@ -1551,11 +1616,14 @@
int sequenceId = resultExtras.requestId;
int32_t burstId = resultExtras.burstId;
+ int64_t frameNumber = resultExtras.frameNumber;
auto it = dev->mSequenceCallbackMap.find(sequenceId);
if (it != dev->mSequenceCallbackMap.end()) {
CallbackHolder cbh = (*it).second;
+ bool v2Callback = cbh.mIs2Callback;
ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
+ ACameraCaptureSession_captureCallback_startV2 onStart2 = cbh.mOnCaptureStarted2;
sp<ACameraCaptureSession> session = cbh.mSession;
if ((size_t) burstId >= cbh.mRequests.size()) {
ALOGE("%s: Error: request index %d out of bound (size %zu)",
@@ -1563,12 +1631,19 @@
dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
}
sp<CaptureRequest> request = cbh.mRequests[burstId];
- sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
+ sp<AMessage> msg = nullptr;
+ if (v2Callback) {
+ msg = new AMessage(kWhatCaptureStart2, dev->mHandler);
+ msg->setPointer(kCallbackFpKey, (void*) onStart2);
+ } else {
+ msg = new AMessage(kWhatCaptureStart, dev->mHandler);
+ msg->setPointer(kCallbackFpKey, (void *)onStart);
+ }
msg->setPointer(kContextKey, cbh.mContext);
msg->setObject(kSessionSpKey, session);
- msg->setPointer(kCallbackFpKey, (void*) onStart);
msg->setObject(kCaptureRequestKey, request);
msg->setInt64(kTimeStampKey, timestamp);
+ msg->setInt64(kFrameNumberKey, frameNumber);
dev->postSessionMsgAndCleanup(msg);
}
return ret;
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index 344d964..17988fe 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -215,6 +215,7 @@
kWhatSessionStateCb, // onReady, onActive
// Capture callbacks
kWhatCaptureStart, // onCaptureStarted
+ kWhatCaptureStart2, // onCaptureStarted
kWhatCaptureResult, // onCaptureProgressed, onCaptureCompleted
kWhatLogicalCaptureResult, // onLogicalCameraCaptureCompleted
kWhatCaptureFail, // onCaptureFailed
@@ -294,11 +295,18 @@
const Vector<sp<CaptureRequest> >& requests,
bool isRepeating,
ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs);
-
- template <class T>
- void initCaptureCallbacks(T* cbs) {
+ CallbackHolder(sp<ACameraCaptureSession> session,
+ const Vector<sp<CaptureRequest> >& requests,
+ bool isRepeating,
+ ACameraCaptureSession_captureCallbacksV2* cbs);
+ CallbackHolder(sp<ACameraCaptureSession> session,
+ const Vector<sp<CaptureRequest> >& requests,
+ bool isRepeating,
+ ACameraCaptureSession_logicalCamera_captureCallbacksV2* lcbs);
+ void clearCallbacks() {
mContext = nullptr;
mOnCaptureStarted = nullptr;
+ mOnCaptureStarted2 = nullptr;
mOnCaptureProgressed = nullptr;
mOnCaptureCompleted = nullptr;
mOnLogicalCameraCaptureCompleted = nullptr;
@@ -307,6 +315,24 @@
mOnCaptureSequenceCompleted = nullptr;
mOnCaptureSequenceAborted = nullptr;
mOnCaptureBufferLost = nullptr;
+ }
+
+ template <class T>
+ void initCaptureCallbacksV2(T* cbs) {
+ clearCallbacks();
+ if (cbs != nullptr) {
+ mContext = cbs->context;
+ mOnCaptureStarted2 = cbs->onCaptureStarted;
+ mOnCaptureProgressed = cbs->onCaptureProgressed;
+ mOnCaptureSequenceCompleted = cbs->onCaptureSequenceCompleted;
+ mOnCaptureSequenceAborted = cbs->onCaptureSequenceAborted;
+ mOnCaptureBufferLost = cbs->onCaptureBufferLost;
+ }
+ }
+
+ template <class T>
+ void initCaptureCallbacks(T* cbs) {
+ clearCallbacks();
if (cbs != nullptr) {
mContext = cbs->context;
mOnCaptureStarted = cbs->onCaptureStarted;
@@ -320,9 +346,11 @@
Vector<sp<CaptureRequest> > mRequests;
const bool mIsRepeating;
const bool mIsLogicalCameraCallback;
+ const bool mIs2Callback;
void* mContext;
ACameraCaptureSession_captureCallback_start mOnCaptureStarted;
+ ACameraCaptureSession_captureCallback_startV2 mOnCaptureStarted2;
ACameraCaptureSession_captureCallback_result mOnCaptureProgressed;
ACameraCaptureSession_captureCallback_result mOnCaptureCompleted;
ACameraCaptureSession_logicalCamera_captureCallback_result mOnLogicalCameraCaptureCompleted;
diff --git a/camera/ndk/include/camera/NdkCameraCaptureSession.h b/camera/ndk/include/camera/NdkCameraCaptureSession.h
index 2b7f040..b0fd00c 100644
--- a/camera/ndk/include/camera/NdkCameraCaptureSession.h
+++ b/camera/ndk/include/camera/NdkCameraCaptureSession.h
@@ -811,6 +811,184 @@
int numRequests, ACaptureRequest** requests,
/*optional*/int* captureSequenceId) __INTRODUCED_IN(29);
+/**
+ * The definition of camera capture start callback. The same as
+ * {@link ACameraCaptureSession_captureCallbacks#onCaptureStarted}, except that
+ * it has the frame number of the capture as well.
+ *
+ * @param context The optional application context provided by user in
+ * {@link ACameraCaptureSession_captureCallbacks}.
+ * @param session The camera capture session of interest.
+ * @param request The capture request that is starting. Note that this pointer points to a copy of
+ * capture request sent by application, so the address is different to what
+ * application sent but the content will match. This request will be freed by
+ * framework immediately after this callback returns.
+ * @param timestamp The timestamp when the capture is started. This timestamp will match
+ * {@link ACAMERA_SENSOR_TIMESTAMP} of the {@link ACameraMetadata} in
+ * {@link ACameraCaptureSession_captureCallbacks#onCaptureCompleted} callback.
+ * @param frameNumber the frame number of the capture started
+ */
+typedef void (*ACameraCaptureSession_captureCallback_startV2)(
+ void* context, ACameraCaptureSession* session,
+ const ACaptureRequest* request, int64_t timestamp, int64_t frameNumber);
+/**
+ * This has the same functionality as ACameraCaptureSession_captureCallbacks,
+ * with the exception that captureCallback_startV2 callback is
+ * used, instead of captureCallback_start, to support retrieving the frame number.
+ */
+typedef struct ACameraCaptureSession_captureCallbacksV2 {
+ /**
+ * Same as ACameraCaptureSession_captureCallbacks
+ */
+ void* context;
+
+ /**
+ * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureStarted},
+ * except that it has the frame number of the capture added in the parameter
+ * list.
+ */
+ ACameraCaptureSession_captureCallback_startV2 onCaptureStarted;
+
+ /**
+ * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureProgressed}.
+ */
+ ACameraCaptureSession_captureCallback_result onCaptureProgressed;
+
+ /**
+ * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureCompleted}.
+ */
+ ACameraCaptureSession_captureCallback_result onCaptureCompleted;
+
+ /**
+ * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureFailed}.
+ */
+ ACameraCaptureSession_captureCallback_failed onCaptureFailed;
+
+ /**
+ * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureSequenceCompleted}.
+ */
+ ACameraCaptureSession_captureCallback_sequenceEnd onCaptureSequenceCompleted;
+
+ /**
+ * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureSequenceAborted}.
+ */
+ ACameraCaptureSession_captureCallback_sequenceAbort onCaptureSequenceAborted;
+
+ /**
+ * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureBufferLost}.
+ */
+ ACameraCaptureSession_captureCallback_bufferLost onCaptureBufferLost;
+
+
+} ACameraCaptureSession_captureCallbacksV2;
+
+/**
+ * This has the same functionality as ACameraCaptureSession_logicalCamera_captureCallbacks,
+ * with the exception that an captureCallback_startV2 callback is
+ * used, instead of captureCallback_start, to support retrieving frame number.
+ */
+typedef struct ACameraCaptureSession_logicalCamera_captureCallbacksV2 {
+ /**
+ * Same as ACameraCaptureSession_captureCallbacks
+ */
+ void* context;
+
+ /**
+ * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureStarted},
+ * except that it has the frame number of the capture added in the parameter
+ * list.
+ */
+ ACameraCaptureSession_captureCallback_startV2 onCaptureStarted;
+
+
+ /**
+ * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureProgressed}.
+ */
+ ACameraCaptureSession_captureCallback_result onCaptureProgressed;
+
+ /**
+ * Same as
+ * {@link ACameraCaptureSession_logicalCamera_captureCallbacks#onLogicalCaptureCompleted}.
+ */
+ ACameraCaptureSession_logicalCamera_captureCallback_result onLogicalCameraCaptureCompleted;
+
+ /**
+ * This callback is called instead of {@link onLogicalCameraCaptureCompleted} when the
+ * camera device failed to produce a capture result for the
+ * request.
+ *
+ * <p>Other requests are unaffected, and some or all image buffers from
+ * the capture may have been pushed to their respective output
+ * streams.</p>
+ *
+ * <p>Note that the ACaptureRequest pointer in the callback will not match what application has
+ * submitted, but the contents the ACaptureRequest will match what application submitted.</p>
+ *
+ * @see ALogicalCameraCaptureFailure
+ */
+ ACameraCaptureSession_logicalCamera_captureCallback_failed onLogicalCameraCaptureFailed;
+
+ /**
+ * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureSequenceCompleted}.
+ */
+ ACameraCaptureSession_captureCallback_sequenceEnd onCaptureSequenceCompleted;
+
+ /**
+ * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureSequenceAborted}.
+ */
+ ACameraCaptureSession_captureCallback_sequenceAbort onCaptureSequenceAborted;
+
+ /**
+ * Same as {@link ACameraCaptureSession_captureCallbacks#onCaptureBufferLost}.
+ */
+ ACameraCaptureSession_captureCallback_bufferLost onCaptureBufferLost;
+
+} ACameraCaptureSession_logicalCamera_captureCallbacksV2;
+
+/**
+ * This has the same functionality as ACameraCaptureSession_capture, with added
+ * support for v2 of camera callbacks, where the onCaptureStarted callback
+ * adds frame number in its parameter list.
+ */
+camera_status_t ACameraCaptureSession_captureV2(
+ ACameraCaptureSession* session,
+ /*optional*/ACameraCaptureSession_captureCallbacksV2* callbacks,
+ int numRequests, ACaptureRequest** requests,
+ /*optional*/int* captureSequenceId) __INTRODUCED_IN(33);
+
+/**
+ * This has the same functionality as ACameraCaptureSession_logical_setRepeatingRequest, with added
+ * support for v2 of logical multi-camera callbacks where the onCaptureStarted
+ * callback adds frame number in its parameter list.
+ */
+camera_status_t ACameraCaptureSession_setRepeatingRequestV2(
+ ACameraCaptureSession* session,
+ /*optional*/ACameraCaptureSession_captureCallbacksV2* callbacks,
+ int numRequests, ACaptureRequest** requests,
+ /*optional*/int* captureSequenceId) __INTRODUCED_IN(33);
+
+/**
+ * This has the same functionality as ACameraCaptureSession_logical_capture, with added
+ * support for v2 of logical multi-camera callbacks where the onCaptureStarted callback
+ * adds frame number in its parameter list.
+ */
+camera_status_t ACameraCaptureSession_logicalCamera_captureV2(
+ ACameraCaptureSession* session,
+ /*optional*/ACameraCaptureSession_logicalCamera_captureCallbacksV2* callbacks,
+ int numRequests, ACaptureRequest** requests,
+ /*optional*/int* captureSequenceId) __INTRODUCED_IN(33);
+
+/**
+ * This has the same functionality as ACameraCaptureSession_logical_setRepeatingRequest, with added
+ * support for v2 of logical multi-camera callbacks where the onCaptureStarted
+ * callback adds frame number in its parameter list.
+ */
+camera_status_t ACameraCaptureSession_logicalCamera_setRepeatingRequestV2(
+ ACameraCaptureSession* session,
+ /*optional*/ACameraCaptureSession_logicalCamera_captureCallbacksV2* callbacks,
+ int numRequests, ACaptureRequest** requests,
+ /*optional*/int* captureSequenceId) __INTRODUCED_IN(33);
+
__END_DECLS
#endif /* _NDK_CAMERA_CAPTURE_SESSION_H */
diff --git a/camera/ndk/libcamera2ndk.map.txt b/camera/ndk/libcamera2ndk.map.txt
index 2b630db..b3977ff 100644
--- a/camera/ndk/libcamera2ndk.map.txt
+++ b/camera/ndk/libcamera2ndk.map.txt
@@ -2,11 +2,15 @@
global:
ACameraCaptureSession_abortCaptures;
ACameraCaptureSession_capture;
+ ACameraCaptureSession_captureV2; # introduced=33
ACameraCaptureSession_logicalCamera_capture; # introduced=29
+ ACameraCaptureSession_logicalCamera_captureV2; # introduced=33
ACameraCaptureSession_close;
ACameraCaptureSession_getDevice;
ACameraCaptureSession_setRepeatingRequest;
+ ACameraCaptureSession_setRepeatingRequestV2; # introduced=33
ACameraCaptureSession_logicalCamera_setRepeatingRequest; # introduced=29
+ ACameraCaptureSession_logicalCamera_setRepeatingRequestV2; # introduced=33
ACameraCaptureSession_stopRepeating;
ACameraCaptureSession_updateSharedOutput; # introduced=28
ACameraDevice_close;
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
index 9f63099..4cc1292 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
@@ -29,8 +29,6 @@
#include "ACaptureRequest.h"
#include "utils.h"
-#include "ACameraCaptureSession.inc"
-
#define CHECK_TRANSACTION_AND_RET(remoteRet, status, callName) \
if (!remoteRet.isOk()) { \
ALOGE("%s: Transaction error during %s call %s", __FUNCTION__, callName, \
@@ -910,6 +908,7 @@
case kWhatOnError:
case kWhatSessionStateCb:
case kWhatCaptureStart:
+ case kWhatCaptureStart2:
case kWhatCaptureResult:
case kWhatLogicalCaptureResult:
case kWhatCaptureFail:
@@ -982,6 +981,7 @@
}
case kWhatSessionStateCb:
case kWhatCaptureStart:
+ case kWhatCaptureStart2:
case kWhatCaptureResult:
case kWhatLogicalCaptureResult:
case kWhatCaptureFail:
@@ -1002,6 +1002,7 @@
const char *id_cstr = mId.c_str();
switch (msg->what()) {
case kWhatCaptureStart:
+ case kWhatCaptureStart2:
case kWhatCaptureResult:
case kWhatLogicalCaptureResult:
case kWhatCaptureFail:
@@ -1053,6 +1054,35 @@
freeACaptureRequest(request);
break;
}
+ case kWhatCaptureStart2:
+ {
+ ACameraCaptureSession_captureCallback_startV2 onStart2;
+ found = msg->findPointer(kCallbackFpKey, (void**) &onStart2);
+ if (!found) {
+ ALOGE("%s: Cannot find capture startV2 callback!", __FUNCTION__);
+ return;
+ }
+ if (onStart2 == nullptr) {
+ return;
+ }
+ int64_t timestamp;
+ found = msg->findInt64(kTimeStampKey, ×tamp);
+ if (!found) {
+ ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
+ return;
+ }
+ int64_t frameNumber;
+ found = msg->findInt64(kFrameNumberKey, &frameNumber);
+ if (!found) {
+ ALOGE("%s: Cannot find frame number!", __FUNCTION__);
+ return;
+ }
+
+ ACaptureRequest* request = allocateACaptureRequest(requestSp, id_cstr);
+ (*onStart2)(context, session.get(), request, timestamp, frameNumber);
+ freeACaptureRequest(request);
+ break;
+ }
case kWhatCaptureResult:
{
ACameraCaptureSession_captureCallback_result onResult;
@@ -1281,6 +1311,7 @@
ACameraCaptureSession_captureCallbacks* cbs) :
mSession(session), mRequests(requests),
mIsRepeating(isRepeating),
+ mIs2Callback(false),
mIsLogicalCameraCallback(false) {
initCaptureCallbacks(cbs);
@@ -1297,6 +1328,7 @@
ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs) :
mSession(session), mRequests(requests),
mIsRepeating(isRepeating),
+ mIs2Callback(false),
mIsLogicalCameraCallback(true) {
initCaptureCallbacks(lcbs);
@@ -1306,6 +1338,40 @@
}
}
+CameraDevice::CallbackHolder::CallbackHolder(
+ sp<ACameraCaptureSession> session,
+ const Vector<sp<CaptureRequest> >& requests,
+ bool isRepeating,
+ ACameraCaptureSession_captureCallbacksV2* cbs) :
+ mSession(session), mRequests(requests),
+ mIsRepeating(isRepeating),
+ mIs2Callback(true),
+ mIsLogicalCameraCallback(false) {
+ initCaptureCallbacksV2(cbs);
+
+ if (cbs != nullptr) {
+ mOnCaptureCompleted = cbs->onCaptureCompleted;
+ mOnCaptureFailed = cbs->onCaptureFailed;
+ }
+}
+
+CameraDevice::CallbackHolder::CallbackHolder(
+ sp<ACameraCaptureSession> session,
+ const Vector<sp<CaptureRequest> >& requests,
+ bool isRepeating,
+ ACameraCaptureSession_logicalCamera_captureCallbacksV2* lcbs) :
+ mSession(session), mRequests(requests),
+ mIsRepeating(isRepeating),
+ mIs2Callback(true),
+ mIsLogicalCameraCallback(true) {
+ initCaptureCallbacksV2(lcbs);
+
+ if (lcbs != nullptr) {
+ mOnLogicalCameraCaptureCompleted = lcbs->onLogicalCameraCaptureCompleted;
+ mOnLogicalCameraCaptureFailed = lcbs->onLogicalCameraCaptureFailed;
+ }
+}
+
void
CameraDevice::checkRepeatingSequenceCompleteLocked(
const int sequenceId, const int64_t lastFrameNumber) {
@@ -1542,11 +1608,14 @@
int32_t sequenceId = resultExtras.requestId;
int32_t burstId = resultExtras.burstId;
+ int64_t frameNumber = resultExtras.frameNumber;
auto it = dev->mSequenceCallbackMap.find(sequenceId);
if (it != dev->mSequenceCallbackMap.end()) {
CallbackHolder cbh = (*it).second;
ACameraCaptureSession_captureCallback_start onStart = cbh.mOnCaptureStarted;
+ ACameraCaptureSession_captureCallback_startV2 onStart2 = cbh.mOnCaptureStarted2;
+ bool v2Callback = cbh.mIs2Callback;
sp<ACameraCaptureSession> session = cbh.mSession;
if ((size_t) burstId >= cbh.mRequests.size()) {
ALOGE("%s: Error: request index %d out of bound (size %zu)",
@@ -1554,12 +1623,19 @@
dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
}
sp<CaptureRequest> request = cbh.mRequests[burstId];
- sp<AMessage> msg = new AMessage(kWhatCaptureStart, dev->mHandler);
+ sp<AMessage> msg = nullptr;
+ if (v2Callback) {
+ msg = new AMessage(kWhatCaptureStart2, dev->mHandler);
+ msg->setPointer(kCallbackFpKey, (void*) onStart2);
+ } else {
+ msg = new AMessage(kWhatCaptureStart, dev->mHandler);
+ msg->setPointer(kCallbackFpKey, (void*) onStart);
+ }
msg->setPointer(kContextKey, cbh.mContext);
msg->setObject(kSessionSpKey, session);
- msg->setPointer(kCallbackFpKey, (void*) onStart);
msg->setObject(kCaptureRequestKey, request);
msg->setInt64(kTimeStampKey, timestamp);
+ msg->setInt64(kFrameNumberKey, frameNumber);
dev->postSessionMsgAndCleanup(msg);
}
return ret;
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.h b/camera/ndk/ndk_vendor/impl/ACameraDevice.h
index 0b6c7c8..c306206 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraDevice.h
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.h
@@ -245,6 +245,7 @@
kWhatSessionStateCb, // onReady, onActive
// Capture callbacks
kWhatCaptureStart, // onCaptureStarted
+ kWhatCaptureStart2, // onCaptureStarted2
kWhatCaptureResult, // onCaptureProgressed, onCaptureCompleted
kWhatLogicalCaptureResult, // onLogicalCameraCaptureCompleted
kWhatCaptureFail, // onCaptureFailed
@@ -309,11 +310,18 @@
const Vector<sp<CaptureRequest>>& requests,
bool isRepeating,
ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs);
-
- template <class T>
- void initCaptureCallbacks(T* cbs) {
+ CallbackHolder(sp<ACameraCaptureSession> session,
+ const Vector<sp<CaptureRequest> >& requests,
+ bool isRepeating,
+ ACameraCaptureSession_captureCallbacksV2* cbs);
+ CallbackHolder(sp<ACameraCaptureSession> session,
+ const Vector<sp<CaptureRequest> >& requests,
+ bool isRepeating,
+ ACameraCaptureSession_logicalCamera_captureCallbacksV2* lcbs);
+ void clearCallbacks() {
mContext = nullptr;
mOnCaptureStarted = nullptr;
+ mOnCaptureStarted2 = nullptr;
mOnCaptureProgressed = nullptr;
mOnCaptureCompleted = nullptr;
mOnLogicalCameraCaptureCompleted = nullptr;
@@ -322,6 +330,24 @@
mOnCaptureSequenceCompleted = nullptr;
mOnCaptureSequenceAborted = nullptr;
mOnCaptureBufferLost = nullptr;
+ }
+
+ template <class T>
+ void initCaptureCallbacksV2(T* cbs) {
+ clearCallbacks();
+ if (cbs != nullptr) {
+ mContext = cbs->context;
+ mOnCaptureStarted2 = cbs->onCaptureStarted;
+ mOnCaptureProgressed = cbs->onCaptureProgressed;
+ mOnCaptureSequenceCompleted = cbs->onCaptureSequenceCompleted;
+ mOnCaptureSequenceAborted = cbs->onCaptureSequenceAborted;
+ mOnCaptureBufferLost = cbs->onCaptureBufferLost;
+ }
+ }
+
+ template <class T>
+ void initCaptureCallbacks(T* cbs) {
+ clearCallbacks();
if (cbs != nullptr) {
mContext = cbs->context;
mOnCaptureStarted = cbs->onCaptureStarted;
@@ -335,10 +361,12 @@
sp<ACameraCaptureSession> mSession;
Vector<sp<CaptureRequest>> mRequests;
const bool mIsRepeating;
+ const bool mIs2Callback;
const bool mIsLogicalCameraCallback;
void* mContext;
ACameraCaptureSession_captureCallback_start mOnCaptureStarted;
+ ACameraCaptureSession_captureCallback_startV2 mOnCaptureStarted2;
ACameraCaptureSession_captureCallback_result mOnCaptureProgressed;
ACameraCaptureSession_captureCallback_result mOnCaptureCompleted;
ACameraCaptureSession_logicalCamera_captureCallback_result mOnLogicalCameraCaptureCompleted;
diff --git a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
index ba14c5c..63cdb76 100644
--- a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
+++ b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
@@ -236,6 +236,11 @@
return ACameraCaptureSession_capture(mSession, &mCaptureCallbacks, 1, &mStillRequest,
&seqId);
}
+ int takePicture2() {
+ int seqId;
+ return ACameraCaptureSession_captureV2(mSession, &mCaptureCallbacksV2, 1,
+ &mStillRequest, &seqId);
+ }
int takeLogicalCameraPicture() {
int seqId;
@@ -243,15 +248,31 @@
1, &mStillRequest, &seqId);
}
+ int takeLogicalCameraPicture2() {
+ int seqId;
+ return ACameraCaptureSession_logicalCamera_captureV2(mSession,
+ &mLogicalCaptureCallbacksV2, 1, &mStillRequest, &seqId);
+ }
+
bool checkCallbacks(int pictureCount) {
std::lock_guard<std::mutex> lock(mMutex);
if (mCompletedCaptureCallbackCount != pictureCount) {
- ALOGE("Completed capture callaback count not as expected. expected %d actual %d",
+ ALOGE("Completed capture callback count not as expected. expected %d actual %d",
pictureCount, mCompletedCaptureCallbackCount);
return false;
}
return true;
}
+ bool checkCallbacksV2(int pictureCount) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (mCaptureStartedCallbackCount != pictureCount) {
+ ALOGE("Capture started callback count not as expected. expected %d actual %d",
+ pictureCount, mCaptureStartedCallbackCount);
+ return false;
+ }
+ return true;
+ }
+
private:
ACameraDevice_StateCallbacks mDeviceCb{this, nullptr, nullptr};
@@ -276,6 +297,7 @@
const char* mCameraId;
ACameraManager* mCameraManager;
int mCompletedCaptureCallbackCount = 0;
+ int mCaptureStartedCallbackCount = 0;
std::mutex mMutex;
ACameraCaptureSession_captureCallbacks mCaptureCallbacks = {
// TODO: Add tests for other callbacks
@@ -293,8 +315,25 @@
nullptr, // onCaptureSequenceAborted
nullptr, // onCaptureBufferLost
};
+ ACameraCaptureSession_captureCallbacksV2 mCaptureCallbacksV2 = {
+ this, // context
+ [](void* ctx , ACameraCaptureSession *,const ACaptureRequest *, int64_t,
+ int64_t frameNumber ) {
+ CameraHelper *ch = static_cast<CameraHelper *>(ctx);
+ ASSERT_TRUE(frameNumber >= 0);
+ std::lock_guard<std::mutex> lock(ch->mMutex);
+ ch->mCaptureStartedCallbackCount++;
+ },
+ nullptr, // onCaptureProgressed
+ nullptr, // onCaptureCompleted
+ nullptr, // onCaptureFailed
+ nullptr, // onCaptureSequenceCompleted
+ nullptr, // onCaptureSequenceAborted
+ nullptr, // onCaptureBufferLost
+ };
std::vector<std::string> mPhysicalCameraIds;
+
ACameraCaptureSession_logicalCamera_captureCallbacks mLogicalCaptureCallbacks = {
// TODO: Add tests for other callbacks
this, // context
@@ -336,6 +375,23 @@
nullptr, // onCaptureSequenceAborted
nullptr, // onCaptureBufferLost
};
+ ACameraCaptureSession_logicalCamera_captureCallbacksV2 mLogicalCaptureCallbacksV2 = {
+ this, // context
+ [](void* ctx , ACameraCaptureSession *,const ACaptureRequest *, int64_t,
+ int64_t frameNumber) {
+ CameraHelper *ch = static_cast<CameraHelper *>(ctx);
+ ASSERT_TRUE(frameNumber >= 0);
+ std::lock_guard<std::mutex> lock(ch->mMutex);
+ ch->mCaptureStartedCallbackCount++;
+ },
+ nullptr, // onCaptureProgressed
+ nullptr, //onLogicalCaptureCompleted
+ nullptr, //onLogicalCpatureFailed
+ nullptr, // onCaptureSequenceCompleted
+ nullptr, // onCaptureSequenceAborted
+ nullptr, // onCaptureBufferLost
+ };
+
};
class ImageReaderTestCase {
@@ -570,7 +626,7 @@
}
bool takePictures(const char* id, uint64_t readerUsage, int readerMaxImages,
- bool readerAsync, int pictureCount) {
+ bool readerAsync, int pictureCount, bool v2 = false) {
int ret = 0;
ImageReaderTestCase testCase(
@@ -600,7 +656,11 @@
}
for (int i = 0; i < pictureCount; i++) {
- ret = cameraHelper.takePicture();
+ if (v2) {
+ ret = cameraHelper.takePicture2();
+ } else {
+ ret = cameraHelper.takePicture();
+ }
if (ret < 0) {
ALOGE("Unable to take picture");
return false;
@@ -617,7 +677,8 @@
}
}
return testCase.getAcquiredImageCount() == pictureCount &&
- cameraHelper.checkCallbacks(pictureCount);
+ v2 ? cameraHelper.checkCallbacksV2(pictureCount) :
+ cameraHelper.checkCallbacks(pictureCount);
}
bool testTakePicturesNative(const char* id) {
@@ -626,12 +687,14 @@
for (auto& readerMaxImages : {1, 4, 8}) {
for (auto& readerAsync : {true, false}) {
for (auto& pictureCount : {1, 4, 8}) {
- if (!takePictures(id, readerUsage, readerMaxImages,
- readerAsync, pictureCount)) {
- ALOGE("Test takePictures failed for test case usage=%" PRIu64
- ", maxImages=%d, async=%d, pictureCount=%d",
- readerUsage, readerMaxImages, readerAsync, pictureCount);
- return false;
+ for ( auto & v2 : {true, false}) {
+ if (!takePictures(id, readerUsage, readerMaxImages,
+ readerAsync, pictureCount, v2)) {
+ ALOGE("Test takePictures failed for test case usage=%" PRIu64
+ ", maxImages=%d, async=%d, pictureCount=%d",
+ readerUsage, readerMaxImages, readerAsync, pictureCount);
+ return false;
+ }
}
}
}
@@ -725,7 +788,7 @@
return;
}
- void testLogicalCameraPhysicalStream(bool usePhysicalSettings) {
+ void testLogicalCameraPhysicalStream(bool usePhysicalSettings, bool v2) {
const char* cameraId = nullptr;
ACameraMetadata* staticMetadata = nullptr;
std::vector<const char*> physicalCameraIds;
@@ -772,7 +835,12 @@
}
for (int i = 0; i < pictureCount; i++) {
- ret = cameraHelper.takeLogicalCameraPicture();
+ if (v2) {
+ ret = cameraHelper.takeLogicalCameraPicture2();
+ }
+ else {
+ ret = cameraHelper.takeLogicalCameraPicture();
+ }
ASSERT_EQ(ret, 0);
}
@@ -793,8 +861,11 @@
ALOGI("Testing window %p", testCase->getNativeWindow());
ASSERT_EQ(testCase->getAcquiredImageCount(), pictureCount);
}
-
- ASSERT_TRUE(cameraHelper.checkCallbacks(pictureCount));
+ if (v2) {
+ ASSERT_TRUE(cameraHelper.checkCallbacksV2(pictureCount));
+ } else {
+ ASSERT_TRUE(cameraHelper.checkCallbacks(pictureCount));
+ }
ACameraMetadata_free(staticMetadata);
}
@@ -834,8 +905,10 @@
}
TEST_F(AImageReaderVendorTest, LogicalCameraPhysicalStream) {
- testLogicalCameraPhysicalStream(false/*usePhysicalSettings*/);
- testLogicalCameraPhysicalStream(true/*usePhysicalSettings*/);
+ for (auto & v2 : {true, false}) {
+ testLogicalCameraPhysicalStream(false/*usePhysicalSettings*/, v2);
+ testLogicalCameraPhysicalStream(true/*usePhysicalSettings*/, v2);
+ }
}
} // namespace