diff options
author | Jianing Wei <jianingwei@google.com> | 2014-04-10 19:53:05 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-04-10 19:53:05 +0000 |
commit | 9e5763aefde93afd375e0d9874e515d7c27b212b (patch) | |
tree | 7bb421efe179aaa521745cc570b208bcb3ba09e1 /services/camera | |
parent | 771386e6e6e79697e2d839ef0f25a242946ba1e5 (diff) | |
parent | cb0652e5a850b2fcd919e977247e87239efaf70e (diff) | |
download | frameworks_av-9e5763aefde93afd375e0d9874e515d7c27b212b.zip frameworks_av-9e5763aefde93afd375e0d9874e515d7c27b212b.tar.gz frameworks_av-9e5763aefde93afd375e0d9874e515d7c27b212b.tar.bz2 |
Merge "CameraService: trigger appropriate callbacks for burst capture."
Diffstat (limited to 'services/camera')
23 files changed, 389 insertions, 309 deletions
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 5c6f653..02bca1f 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -1116,7 +1116,8 @@ void CameraService::BasicClient::opChanged(int32_t op, const String16& packageNa // Reset the client PID to allow server-initiated disconnect, // and to prevent further calls by client. mClientPid = getCallingPid(); - notifyError(); + CaptureResultExtras resultExtras; // a dummy result (invalid) + notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, resultExtras); disconnect(); } } @@ -1145,7 +1146,8 @@ CameraService::Client* CameraService::Client::getClientFromCookie(void* user) { return client; } -void CameraService::Client::notifyError() { +void CameraService::Client::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode, + const CaptureResultExtras& resultExtras) { mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0); } @@ -1199,7 +1201,8 @@ CameraService::ProClient::ProClient(const sp<CameraService>& cameraService, CameraService::ProClient::~ProClient() { } -void CameraService::ProClient::notifyError() { +void CameraService::ProClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode, + const CaptureResultExtras& resultExtras) { mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0); } diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 8853e48..76ea7be 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -31,6 +31,7 @@ #include <camera/camera2/ICameraDeviceUser.h> #include <camera/camera2/ICameraDeviceCallbacks.h> #include <camera/VendorTagDescriptor.h> +#include <camera/CaptureResult.h> #include <camera/ICameraServiceListener.h> @@ -182,7 +183,9 @@ public: status_t finishCameraOps(); // Notify client about a fatal error - virtual void notifyError() = 0; + virtual void notifyError( + ICameraDeviceCallbacks::CameraErrorCode errorCode, + const CaptureResultExtras& resultExtras) = 0; private: AppOpsManager mAppOpsManager; @@ -259,7 +262,8 @@ public: // convert client from cookie. Client lock should be acquired before getting Client. static Client* getClientFromCookie(void* user); - virtual void notifyError(); + virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode, + const CaptureResultExtras& resultExtras); // Initialized in constructor @@ -307,7 +311,8 @@ public: virtual void onExclusiveLockStolen() = 0; protected: - virtual void notifyError(); + virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode, + const CaptureResultExtras& resultExtras); sp<IProCameraCallbacks> mRemoteCallback; }; // class ProClient diff --git a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp index f5c28ed..e5f5064 100644 --- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp +++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp @@ -106,13 +106,12 @@ void CaptureSequencer::notifyAutoExposure(uint8_t newState, int triggerId) { } } -void CaptureSequencer::onFrameAvailable(int32_t requestId, - const CameraMetadata &frame) { - ALOGV("%s: Listener found new frame", __FUNCTION__); +void CaptureSequencer::onResultAvailable(const CaptureResult &result) { ATRACE_CALL(); + ALOGV("%s: New result available.", __FUNCTION__); Mutex::Autolock l(mInputMutex); - mNewFrameId = requestId; - mNewFrame = frame; + mNewFrameId = result.mResultExtras.requestId; + mNewFrame = result.mMetadata; if (!mNewFrameReceived) { mNewFrameReceived = true; mNewFrameSignal.signal(); diff --git a/services/camera/libcameraservice/api1/client2/CaptureSequencer.h b/services/camera/libcameraservice/api1/client2/CaptureSequencer.h index 9fb4ee7..d42ab13 100644 --- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.h +++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.h @@ -24,6 +24,7 @@ #include <utils/Mutex.h> #include <utils/Condition.h> #include "camera/CameraMetadata.h" +#include "camera/CaptureResult.h" #include "Parameters.h" #include "FrameProcessor.h" @@ -61,8 +62,8 @@ class CaptureSequencer: // Notifications about AE state changes void notifyAutoExposure(uint8_t newState, int triggerId); - // Notifications from the frame processor - virtual void onFrameAvailable(int32_t requestId, const CameraMetadata &frame); + // Notification from the frame processor + virtual void onResultAvailable(const CaptureResult &result); // Notifications from the JPEG processor void onCaptureAvailable(nsecs_t timestamp, sp<MemoryBase> captureBuffer); diff --git a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp index dd5b27c..69bea24 100644 --- a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp @@ -55,7 +55,7 @@ FrameProcessor::FrameProcessor(wp<CameraDeviceBase> device, FrameProcessor::~FrameProcessor() { } -bool FrameProcessor::processSingleFrame(CameraMetadata &frame, +bool FrameProcessor::processSingleFrame(CaptureResult &frame, const sp<CameraDeviceBase> &device) { sp<Camera2Client> client = mClient.promote(); @@ -66,19 +66,19 @@ bool FrameProcessor::processSingleFrame(CameraMetadata &frame, bool partialResult = false; if (mUsePartialQuirk) { camera_metadata_entry_t entry; - entry = frame.find(ANDROID_QUIRKS_PARTIAL_RESULT); + entry = frame.mMetadata.find(ANDROID_QUIRKS_PARTIAL_RESULT); if (entry.count > 0 && entry.data.u8[0] == ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) { partialResult = true; } } - if (!partialResult && processFaceDetect(frame, client) != OK) { + if (!partialResult && processFaceDetect(frame.mMetadata, client) != OK) { return false; } if (mSynthesize3ANotify) { - process3aState(frame, client); + process3aState(frame.mMetadata, client); } return FrameProcessorBase::processSingleFrame(frame, device); diff --git a/services/camera/libcameraservice/api1/client2/FrameProcessor.h b/services/camera/libcameraservice/api1/client2/FrameProcessor.h index 856ad32..514bd1a 100644 --- a/services/camera/libcameraservice/api1/client2/FrameProcessor.h +++ b/services/camera/libcameraservice/api1/client2/FrameProcessor.h @@ -51,7 +51,7 @@ class FrameProcessor : public FrameProcessorBase { void processNewFrames(const sp<Camera2Client> &client); - virtual bool processSingleFrame(CameraMetadata &frame, + virtual bool processSingleFrame(CaptureResult &frame, const sp<CameraDeviceBase> &device); status_t processFaceDetect(const CameraMetadata &frame, diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp index 6ab9e1a..2a2a5af 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp @@ -73,18 +73,19 @@ void ZslProcessor::onFrameAvailable() { } } -void ZslProcessor::onFrameAvailable(int32_t /*requestId*/, - const CameraMetadata &frame) { +void ZslProcessor::onResultAvailable(const CaptureResult &result) { + ATRACE_CALL(); + ALOGV("%s:", __FUNCTION__); Mutex::Autolock l(mInputMutex); camera_metadata_ro_entry_t entry; - entry = frame.find(ANDROID_SENSOR_TIMESTAMP); + entry = result.mMetadata.find(ANDROID_SENSOR_TIMESTAMP); nsecs_t timestamp = entry.data.i64[0]; (void)timestamp; ALOGVV("Got preview frame for timestamp %" PRId64, timestamp); if (mState != RUNNING) return; - mFrameList.editItemAt(mFrameListHead) = frame; + mFrameList.editItemAt(mFrameListHead) = result.mMetadata; mFrameListHead = (mFrameListHead + 1) % kFrameListDepth; findMatchesLocked(); diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.h b/services/camera/libcameraservice/api1/client2/ZslProcessor.h index 6d3cb85..f4cf0c8 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessor.h +++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.h @@ -24,6 +24,7 @@ #include <utils/Condition.h> #include <gui/BufferItemConsumer.h> #include <camera/CameraMetadata.h> +#include <camera/CaptureResult.h> #include "common/CameraDeviceBase.h" #include "api1/client2/ZslProcessorInterface.h" @@ -54,7 +55,7 @@ class ZslProcessor: // From mZslConsumer virtual void onFrameAvailable(); // From FrameProcessor - virtual void onFrameAvailable(int32_t requestId, const CameraMetadata &frame); + virtual void onResultAvailable(const CaptureResult &result); virtual void onBufferReleased(buffer_handle_t *handle); diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp index 3949b90..1dcb718 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp +++ b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp @@ -63,18 +63,19 @@ ZslProcessor3::~ZslProcessor3() { deleteStream(); } -void ZslProcessor3::onFrameAvailable(int32_t /*requestId*/, - const CameraMetadata &frame) { +void ZslProcessor3::onResultAvailable(const CaptureResult &result) { + ATRACE_CALL(); + ALOGV("%s:", __FUNCTION__); Mutex::Autolock l(mInputMutex); camera_metadata_ro_entry_t entry; - entry = frame.find(ANDROID_SENSOR_TIMESTAMP); + entry = result.mMetadata.find(ANDROID_SENSOR_TIMESTAMP); nsecs_t timestamp = entry.data.i64[0]; (void)timestamp; ALOGVV("Got preview metadata for timestamp %" PRId64, timestamp); if (mState != RUNNING) return; - mFrameList.editItemAt(mFrameListHead) = frame; + mFrameList.editItemAt(mFrameListHead) = result.mMetadata; mFrameListHead = (mFrameListHead + 1) % kFrameListDepth; } diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor3.h b/services/camera/libcameraservice/api1/client2/ZslProcessor3.h index d2f8322..4c52a64 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessor3.h +++ b/services/camera/libcameraservice/api1/client2/ZslProcessor3.h @@ -50,8 +50,8 @@ class ZslProcessor3 : ZslProcessor3(sp<Camera2Client> client, wp<CaptureSequencer> sequencer); ~ZslProcessor3(); - // From FrameProcessor - virtual void onFrameAvailable(int32_t requestId, const CameraMetadata &frame); + // From FrameProcessor::FilteredListener + virtual void onResultAvailable(const CaptureResult &result); /** **************************************** diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp index 1c9a342..3d85e90 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp @@ -16,7 +16,7 @@ #define LOG_TAG "CameraDeviceClient" #define ATRACE_TAG ATRACE_TAG_CAMERA -// #define LOG_NDEBUG 0 +//#define LOG_NDEBUG 0 #include <cutils/properties.h> #include <utils/Log.h> @@ -91,105 +91,18 @@ CameraDeviceClient::~CameraDeviceClient() { } status_t CameraDeviceClient::submitRequest(sp<CaptureRequest> request, - bool streaming) { - ATRACE_CALL(); - ALOGV("%s", __FUNCTION__); - - status_t res; - - if ( (res = checkPid(__FUNCTION__) ) != OK) return res; - - Mutex::Autolock icl(mBinderSerializationLock); - - if (!mDevice.get()) return DEAD_OBJECT; - - if (request == 0) { - ALOGE("%s: Camera %d: Sent null request. Rejecting request.", - __FUNCTION__, mCameraId); - return BAD_VALUE; - } - - CameraMetadata metadata(request->mMetadata); - - if (metadata.isEmpty()) { - ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.", - __FUNCTION__, mCameraId); - return BAD_VALUE; - } else if (request->mSurfaceList.size() == 0) { - ALOGE("%s: Camera %d: Requests must have at least one surface target. " - "Rejecting request.", __FUNCTION__, mCameraId); - return BAD_VALUE; - } - - if (!enforceRequestPermissions(metadata)) { - // Callee logs - return PERMISSION_DENIED; - } - - /** - * Write in the output stream IDs which we calculate from - * the capture request's list of surface targets - */ - Vector<int32_t> outputStreamIds; - outputStreamIds.setCapacity(request->mSurfaceList.size()); - for (size_t i = 0; i < request->mSurfaceList.size(); ++i) { - sp<Surface> surface = request->mSurfaceList[i]; - - if (surface == 0) continue; - - sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer(); - int idx = mStreamMap.indexOfKey(gbp->asBinder()); - - // Trying to submit request with surface that wasn't created - if (idx == NAME_NOT_FOUND) { - ALOGE("%s: Camera %d: Tried to submit a request with a surface that" - " we have not called createStream on", - __FUNCTION__, mCameraId); - return BAD_VALUE; - } - - int streamId = mStreamMap.valueAt(idx); - outputStreamIds.push_back(streamId); - ALOGV("%s: Camera %d: Appending output stream %d to request", - __FUNCTION__, mCameraId, streamId); - } - - metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0], - outputStreamIds.size()); - - int32_t requestId = mRequestIdCounter++; - metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1); - ALOGV("%s: Camera %d: Creating request with ID %d", - __FUNCTION__, mCameraId, requestId); - - if (streaming) { - res = mDevice->setStreamingRequest(metadata); - if (res != OK) { - ALOGE("%s: Camera %d: Got error %d after trying to set streaming " - "request", __FUNCTION__, mCameraId, res); - } else { - mStreamingRequestList.push_back(requestId); - } - } else { - res = mDevice->capture(metadata); - if (res != OK) { - ALOGE("%s: Camera %d: Got error %d after trying to set capture", - __FUNCTION__, mCameraId, res); - } - } - - ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId); - if (res == OK) { - return requestId; - } - - return res; + bool streaming, + /*out*/ + int64_t* lastFrameNumber) { + List<sp<CaptureRequest> > requestList; + requestList.push_back(request); + return submitRequestList(requestList, streaming, lastFrameNumber); } status_t CameraDeviceClient::submitRequestList(List<sp<CaptureRequest> > requests, - bool streaming) { + bool streaming, int64_t* lastFrameNumber) { ATRACE_CALL(); - ALOGV("%s-start of function", __FUNCTION__); + ALOGV("%s-start of function. Request list size %d", __FUNCTION__, requests.size()); status_t res; if ( (res = checkPid(__FUNCTION__) ) != OK) return res; @@ -238,9 +151,8 @@ status_t CameraDeviceClient::submitRequestList(List<sp<CaptureRequest> > request */ Vector<int32_t> outputStreamIds; outputStreamIds.setCapacity(request->mSurfaceList.size()); - for (Vector<sp<Surface> >::iterator surfaceIt = 0; - surfaceIt != request->mSurfaceList.end(); ++surfaceIt) { - sp<Surface> surface = *surfaceIt; + for (size_t i = 0; i < request->mSurfaceList.size(); ++i) { + sp<Surface> surface = request->mSurfaceList[i]; if (surface == 0) continue; sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer(); @@ -273,7 +185,7 @@ status_t CameraDeviceClient::submitRequestList(List<sp<CaptureRequest> > request mRequestIdCounter++; if (streaming) { - res = mDevice->setStreamingRequestList(metadataRequestList); + res = mDevice->setStreamingRequestList(metadataRequestList, lastFrameNumber); if (res != OK) { ALOGE("%s: Camera %d: Got error %d after trying to set streaming " "request", __FUNCTION__, mCameraId, res); @@ -281,11 +193,12 @@ status_t CameraDeviceClient::submitRequestList(List<sp<CaptureRequest> > request mStreamingRequestList.push_back(requestId); } } else { - res = mDevice->captureList(metadataRequestList); + res = mDevice->captureList(metadataRequestList, lastFrameNumber); if (res != OK) { ALOGE("%s: Camera %d: Got error %d after trying to set capture", __FUNCTION__, mCameraId, res); } + ALOGV("%s: requestId = %d ", __FUNCTION__, requestId); } ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId); @@ -296,7 +209,7 @@ status_t CameraDeviceClient::submitRequestList(List<sp<CaptureRequest> > request return res; } -status_t CameraDeviceClient::cancelRequest(int requestId) { +status_t CameraDeviceClient::cancelRequest(int requestId, int64_t* lastFrameNumber) { ATRACE_CALL(); ALOGV("%s, requestId = %d", __FUNCTION__, requestId); @@ -322,7 +235,7 @@ status_t CameraDeviceClient::cancelRequest(int requestId) { return BAD_VALUE; } - res = mDevice->clearStreamingRequest(); + res = mDevice->clearStreamingRequest(lastFrameNumber); if (res == OK) { ALOGV("%s: Camera %d: Successfully cleared streaming request", @@ -369,8 +282,6 @@ status_t CameraDeviceClient::deleteStream(int streamId) { } else if (res == OK) { mStreamMap.removeItemsAt(index); - ALOGV("%s: Camera %d: Successfully deleted stream ID (%d)", - __FUNCTION__, mCameraId, streamId); } return res; @@ -575,7 +486,7 @@ status_t CameraDeviceClient::waitUntilIdle() return res; } -status_t CameraDeviceClient::flush() { +status_t CameraDeviceClient::flush(int64_t* lastFrameNumber) { ATRACE_CALL(); ALOGV("%s", __FUNCTION__); @@ -586,7 +497,7 @@ status_t CameraDeviceClient::flush() { if (!mDevice.get()) return DEAD_OBJECT; - return mDevice->flush(); + return mDevice->flush(lastFrameNumber); } status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) { @@ -603,13 +514,13 @@ status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) { return dumpDevice(fd, args); } - -void CameraDeviceClient::notifyError() { +void CameraDeviceClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode, + const CaptureResultExtras& resultExtras) { // Thread safe. Don't bother locking. sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback(); if (remoteCb != 0) { - remoteCb->onDeviceError(ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE); + remoteCb->onDeviceError(errorCode, resultExtras); } } @@ -622,12 +533,12 @@ void CameraDeviceClient::notifyIdle() { } } -void CameraDeviceClient::notifyShutter(int requestId, +void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras, nsecs_t timestamp) { // Thread safe. Don't bother locking. sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback(); if (remoteCb != 0) { - remoteCb->onCaptureStarted(requestId, timestamp); + remoteCb->onCaptureStarted(resultExtras, timestamp); } } @@ -662,16 +573,14 @@ void CameraDeviceClient::detachDevice() { } /** Device-related methods */ -void CameraDeviceClient::onFrameAvailable(int32_t requestId, - const CameraMetadata& frame) { +void CameraDeviceClient::onResultAvailable(const CaptureResult& result) { ATRACE_CALL(); ALOGV("%s", __FUNCTION__); // Thread-safe. No lock necessary. sp<ICameraDeviceCallbacks> remoteCb = mRemoteCallback; if (remoteCb != NULL) { - ALOGV("%s: frame = %p ", __FUNCTION__, &frame); - remoteCb->onResultReceived(requestId, frame); + remoteCb->onResultReceived(result.mMetadata, result.mResultExtras); } } diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h index e96e1ae..0b37784 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.h +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h @@ -64,11 +64,17 @@ public: // Note that the callee gets a copy of the metadata. virtual status_t submitRequest(sp<CaptureRequest> request, - bool streaming = false); + bool streaming = false, + /*out*/ + int64_t* lastFrameNumber = NULL); // List of requests are copied. virtual status_t submitRequestList(List<sp<CaptureRequest> > requests, - bool streaming = false); - virtual status_t cancelRequest(int requestId); + bool streaming = false, + /*out*/ + int64_t* lastFrameNumber = NULL); + virtual status_t cancelRequest(int requestId, + /*out*/ + int64_t* lastFrameNumber = NULL); // Returns -EBUSY if device is not idle virtual status_t deleteStream(int streamId); @@ -92,7 +98,8 @@ public: virtual status_t waitUntilIdle(); // Flush all active and pending requests as fast as possible - virtual status_t flush(); + virtual status_t flush(/*out*/ + int64_t* lastFrameNumber = NULL); /** * Interface used by CameraService @@ -117,16 +124,16 @@ public: */ virtual void notifyIdle(); - virtual void notifyError(); - virtual void notifyShutter(int requestId, nsecs_t timestamp); + virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode, + const CaptureResultExtras& resultExtras); + virtual void notifyShutter(const CaptureResultExtras& resultExtras, nsecs_t timestamp); /** * Interface used by independent components of CameraDeviceClient. */ protected: /** FilteredListener implementation **/ - virtual void onFrameAvailable(int32_t requestId, - const CameraMetadata& frame); + virtual void onResultAvailable(const CaptureResult& result); virtual void detachDevice(); // Calculate the ANativeWindow transform from android.sensor.orientation diff --git a/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp b/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp index 1a7a7a7..0f6d278 100644 --- a/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp +++ b/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp @@ -373,9 +373,7 @@ void ProCamera2Client::detachDevice() { Camera2ClientBase::detachDevice(); } -/** Device-related methods */ -void ProCamera2Client::onFrameAvailable(int32_t requestId, - const CameraMetadata& frame) { +void ProCamera2Client::onResultAvailable(const CaptureResult& result) { ATRACE_CALL(); ALOGV("%s", __FUNCTION__); @@ -383,13 +381,12 @@ void ProCamera2Client::onFrameAvailable(int32_t requestId, SharedCameraCallbacks::Lock l(mSharedCameraCallbacks); if (mRemoteCallback != NULL) { - CameraMetadata tmp(frame); + CameraMetadata tmp(result.mMetadata); camera_metadata_t* meta = tmp.release(); ALOGV("%s: meta = %p ", __FUNCTION__, meta); - mRemoteCallback->onResultReceived(requestId, meta); + mRemoteCallback->onResultReceived(result.mResultExtras.requestId, meta); tmp.acquire(meta); } - } bool ProCamera2Client::enforceRequestPermissions(CameraMetadata& metadata) { diff --git a/services/camera/libcameraservice/api_pro/ProCamera2Client.h b/services/camera/libcameraservice/api_pro/ProCamera2Client.h index 8a0f547..9d83122 100644 --- a/services/camera/libcameraservice/api_pro/ProCamera2Client.h +++ b/services/camera/libcameraservice/api_pro/ProCamera2Client.h @@ -21,6 +21,7 @@ #include "common/FrameProcessorBase.h" #include "common/Camera2ClientBase.h" #include "device2/Camera2Device.h" +#include "camera/CaptureResult.h" namespace android { @@ -97,8 +98,8 @@ public: protected: /** FilteredListener implementation **/ - virtual void onFrameAvailable(int32_t requestId, - const CameraMetadata& frame); + virtual void onResultAvailable(const CaptureResult& result); + virtual void detachDevice(); private: diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp index 6a88c87..19efd30 100644 --- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp +++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp @@ -221,10 +221,11 @@ status_t Camera2ClientBase<TClientBase>::connect( /** Device-related methods */ template <typename TClientBase> -void Camera2ClientBase<TClientBase>::notifyError(int errorCode, int arg1, - int arg2) { - ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, - arg1, arg2); +void Camera2ClientBase<TClientBase>::notifyError( + ICameraDeviceCallbacks::CameraErrorCode errorCode, + const CaptureResultExtras& resultExtras) { + ALOGE("Error condition %d reported by HAL, requestId %" PRId32, errorCode, + resultExtras.requestId); } template <typename TClientBase> @@ -233,13 +234,13 @@ void Camera2ClientBase<TClientBase>::notifyIdle() { } template <typename TClientBase> -void Camera2ClientBase<TClientBase>::notifyShutter(int requestId, +void Camera2ClientBase<TClientBase>::notifyShutter(const CaptureResultExtras& resultExtras, nsecs_t timestamp) { - (void)requestId; + (void)resultExtras; (void)timestamp; - ALOGV("%s: Shutter notification for request id %d at time %" PRId64, - __FUNCTION__, requestId, timestamp); + ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64, + __FUNCTION__, resultExtras.requestId, timestamp); } template <typename TClientBase> diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h index 61e44f0..9feca93 100644 --- a/services/camera/libcameraservice/common/Camera2ClientBase.h +++ b/services/camera/libcameraservice/common/Camera2ClientBase.h @@ -18,6 +18,7 @@ #define ANDROID_SERVERS_CAMERA_CAMERA2CLIENT_BASE_H #include "common/CameraDeviceBase.h" +#include "camera/CaptureResult.h" namespace android { @@ -61,9 +62,11 @@ public: * CameraDeviceBase::NotificationListener implementation */ - virtual void notifyError(int errorCode, int arg1, int arg2); + virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode, + const CaptureResultExtras& resultExtras); virtual void notifyIdle(); - virtual void notifyShutter(int requestId, nsecs_t timestamp); + virtual void notifyShutter(const CaptureResultExtras& resultExtras, + nsecs_t timestamp); virtual void notifyAutoFocus(uint8_t newState, int triggerId); virtual void notifyAutoExposure(uint8_t newState, int triggerId); virtual void notifyAutoWhitebalance(uint8_t newState, diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h index a4ae179..7597b10 100644 --- a/services/camera/libcameraservice/common/CameraDeviceBase.h +++ b/services/camera/libcameraservice/common/CameraDeviceBase.h @@ -24,8 +24,10 @@ #include <utils/Timers.h> #include <utils/List.h> +#include <camera/camera2/ICameraDeviceCallbacks.h> #include "hardware/camera2.h" #include "camera/CameraMetadata.h" +#include "camera/CaptureResult.h" namespace android { @@ -45,7 +47,7 @@ class CameraDeviceBase : public virtual RefBase { virtual status_t initialize(camera_module_t *module) = 0; virtual status_t disconnect() = 0; - virtual status_t dump(int fd, const Vector<String16>& args) = 0; + virtual status_t dump(int fd, const Vector<String16> &args) = 0; /** * The device's static characteristics metadata buffer @@ -55,29 +57,37 @@ class CameraDeviceBase : public virtual RefBase { /** * Submit request for capture. The CameraDevice takes ownership of the * passed-in buffer. + * Output lastFrameNumber is the expected frame number of this request. */ - virtual status_t capture(CameraMetadata &request) = 0; + virtual status_t capture(CameraMetadata &request, int64_t *lastFrameNumber = NULL) = 0; /** * Submit a list of requests. + * Output lastFrameNumber is the expected last frame number of the list of requests. */ - virtual status_t captureList(const List<const CameraMetadata> &requests) = 0; + virtual status_t captureList(const List<const CameraMetadata> &requests, + int64_t *lastFrameNumber = NULL) = 0; /** * Submit request for streaming. The CameraDevice makes a copy of the * passed-in buffer and the caller retains ownership. + * Output lastFrameNumber is the last frame number of the previous streaming request. */ - virtual status_t setStreamingRequest(const CameraMetadata &request) = 0; + virtual status_t setStreamingRequest(const CameraMetadata &request, + int64_t *lastFrameNumber = NULL) = 0; /** * Submit a list of requests for streaming. + * Output lastFrameNumber is the last frame number of the previous streaming request. */ - virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests) = 0; + virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests, + int64_t *lastFrameNumber = NULL) = 0; /** * Clear the streaming request slot. + * Output lastFrameNumber is the last frame number of the previous streaming request. */ - virtual status_t clearStreamingRequest() = 0; + virtual status_t clearStreamingRequest(int64_t *lastFrameNumber = NULL) = 0; /** * Wait until a request with the given ID has been dequeued by the @@ -153,11 +163,12 @@ class CameraDeviceBase : public virtual RefBase { // API1 and API2. // Required for API 1 and 2 - virtual void notifyError(int errorCode, int arg1, int arg2) = 0; + virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode, + const CaptureResultExtras &resultExtras) = 0; // Required only for API2 virtual void notifyIdle() = 0; - virtual void notifyShutter(int requestId, + virtual void notifyShutter(const CaptureResultExtras &resultExtras, nsecs_t timestamp) = 0; // Required only for API1 @@ -190,11 +201,12 @@ class CameraDeviceBase : public virtual RefBase { virtual status_t waitForNextFrame(nsecs_t timeout) = 0; /** - * Get next metadata frame from the frame queue. Returns NULL if the queue - * is empty; caller takes ownership of the metadata buffer. - * May be called concurrently to most methods, except for waitForNextFrame + * Get next capture result frame from the result queue. Returns NOT_ENOUGH_DATA + * if the queue is empty; caller takes ownership of the metadata buffer inside + * the capture result object's metadata field. + * May be called concurrently to most methods, except for waitForNextFrame. */ - virtual status_t getNextFrame(CameraMetadata *frame) = 0; + virtual status_t getNextResult(CaptureResult *frame) = 0; /** * Trigger auto-focus. The latest ID used in a trigger autofocus or cancel @@ -235,8 +247,9 @@ class CameraDeviceBase : public virtual RefBase { /** * Flush all pending and in-flight requests. Blocks until flush is * complete. + * Output lastFrameNumber is the last frame number of the previous streaming request. */ - virtual status_t flush() = 0; + virtual status_t flush(int64_t *lastFrameNumber = NULL) = 0; }; diff --git a/services/camera/libcameraservice/common/FrameProcessorBase.cpp b/services/camera/libcameraservice/common/FrameProcessorBase.cpp index 4d31667..f6a971a 100644 --- a/services/camera/libcameraservice/common/FrameProcessorBase.cpp +++ b/services/camera/libcameraservice/common/FrameProcessorBase.cpp @@ -99,15 +99,17 @@ bool FrameProcessorBase::threadLoop() { void FrameProcessorBase::processNewFrames(const sp<CameraDeviceBase> &device) { status_t res; ATRACE_CALL(); - CameraMetadata frame; + CaptureResult result; ALOGV("%s: Camera %d: Process new frames", __FUNCTION__, device->getId()); - while ( (res = device->getNextFrame(&frame)) == OK) { + while ( (res = device->getNextResult(&result)) == OK) { + // TODO: instead of getting frame number from metadata, we should read + // this from result.mResultExtras when CameraDeviceBase interface is fixed. camera_metadata_entry_t entry; - entry = frame.find(ANDROID_REQUEST_FRAME_COUNT); + entry = result.mMetadata.find(ANDROID_REQUEST_FRAME_COUNT); if (entry.count == 0) { ALOGE("%s: Camera %d: Error reading frame number", __FUNCTION__, device->getId()); @@ -115,13 +117,13 @@ void FrameProcessorBase::processNewFrames(const sp<CameraDeviceBase> &device) { } ATRACE_INT("cam2_frame", entry.data.i32[0]); - if (!processSingleFrame(frame, device)) { + if (!processSingleFrame(result, device)) { break; } - if (!frame.isEmpty()) { + if (!result.mMetadata.isEmpty()) { Mutex::Autolock al(mLastFrameMutex); - mLastFrame.acquire(frame); + mLastFrame.acquire(result.mMetadata); } } if (res != NOT_ENOUGH_DATA) { @@ -133,21 +135,22 @@ void FrameProcessorBase::processNewFrames(const sp<CameraDeviceBase> &device) { return; } -bool FrameProcessorBase::processSingleFrame(CameraMetadata &frame, - const sp<CameraDeviceBase> &device) { +bool FrameProcessorBase::processSingleFrame(CaptureResult &result, + const sp<CameraDeviceBase> &device) { ALOGV("%s: Camera %d: Process single frame (is empty? %d)", - __FUNCTION__, device->getId(), frame.isEmpty()); - return processListeners(frame, device) == OK; + __FUNCTION__, device->getId(), result.mMetadata.isEmpty()); + return processListeners(result, device) == OK; } -status_t FrameProcessorBase::processListeners(const CameraMetadata &frame, +status_t FrameProcessorBase::processListeners(const CaptureResult &result, const sp<CameraDeviceBase> &device) { ATRACE_CALL(); + camera_metadata_ro_entry_t entry; // Quirks: Don't deliver partial results to listeners that don't want them bool quirkIsPartial = false; - entry = frame.find(ANDROID_QUIRKS_PARTIAL_RESULT); + entry = result.mMetadata.find(ANDROID_QUIRKS_PARTIAL_RESULT); if (entry.count != 0 && entry.data.u8[0] == ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) { ALOGV("%s: Camera %d: Not forwarding partial result to listeners", @@ -155,10 +158,13 @@ status_t FrameProcessorBase::processListeners(const CameraMetadata &frame, quirkIsPartial = true; } - entry = frame.find(ANDROID_REQUEST_ID); + // TODO: instead of getting requestID from CameraMetadata, we should get it + // from CaptureResultExtras. This will require changing Camera2Device. + // Currently Camera2Device uses MetadataQueue to store results, which does not + // include CaptureResultExtras. + entry = result.mMetadata.find(ANDROID_REQUEST_ID); if (entry.count == 0) { - ALOGE("%s: Camera %d: Error reading frame id", - __FUNCTION__, device->getId()); + ALOGE("%s: Camera %d: Error reading frame id", __FUNCTION__, device->getId()); return BAD_VALUE; } int32_t requestId = entry.data.i32[0]; @@ -169,9 +175,8 @@ status_t FrameProcessorBase::processListeners(const CameraMetadata &frame, List<RangeListener>::iterator item = mRangeListeners.begin(); while (item != mRangeListeners.end()) { - if (requestId >= item->minId && - requestId < item->maxId && - (!quirkIsPartial || item->quirkSendPartials) ) { + if (requestId >= item->minId && requestId < item->maxId && + (!quirkIsPartial || item->quirkSendPartials)) { sp<FilteredListener> listener = item->listener.promote(); if (listener == 0) { item = mRangeListeners.erase(item); @@ -183,10 +188,12 @@ status_t FrameProcessorBase::processListeners(const CameraMetadata &frame, item++; } } - ALOGV("Got %zu range listeners out of %zu", listeners.size(), mRangeListeners.size()); + ALOGV("%s: Camera %d: Got %zu range listeners out of %zu", __FUNCTION__, + device->getId(), listeners.size(), mRangeListeners.size()); + List<sp<FilteredListener> >::iterator item = listeners.begin(); for (; item != listeners.end(); item++) { - (*item)->onFrameAvailable(requestId, frame); + (*item)->onResultAvailable(result); } return OK; } diff --git a/services/camera/libcameraservice/common/FrameProcessorBase.h b/services/camera/libcameraservice/common/FrameProcessorBase.h index 89b608a..15a014e 100644 --- a/services/camera/libcameraservice/common/FrameProcessorBase.h +++ b/services/camera/libcameraservice/common/FrameProcessorBase.h @@ -23,6 +23,7 @@ #include <utils/KeyedVector.h> #include <utils/List.h> #include <camera/CameraMetadata.h> +#include <camera/CaptureResult.h> namespace android { @@ -39,8 +40,7 @@ class FrameProcessorBase: public Thread { virtual ~FrameProcessorBase(); struct FilteredListener: virtual public RefBase { - virtual void onFrameAvailable(int32_t requestId, - const CameraMetadata &frame) = 0; + virtual void onResultAvailable(const CaptureResult &result) = 0; }; // Register a listener for a range of IDs [minId, maxId). Multiple listeners @@ -72,10 +72,10 @@ class FrameProcessorBase: public Thread { void processNewFrames(const sp<CameraDeviceBase> &device); - virtual bool processSingleFrame(CameraMetadata &frame, + virtual bool processSingleFrame(CaptureResult &result, const sp<CameraDeviceBase> &device); - status_t processListeners(const CameraMetadata &frame, + status_t processListeners(const CaptureResult &result, const sp<CameraDeviceBase> &device); CameraMetadata mLastFrame; diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp index 0cc3a04..c33c166 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.cpp +++ b/services/camera/libcameraservice/device2/Camera2Device.cpp @@ -199,7 +199,7 @@ const CameraMetadata& Camera2Device::info() const { return mDeviceInfo; } -status_t Camera2Device::capture(CameraMetadata &request) { +status_t Camera2Device::capture(CameraMetadata &request, int64_t* /*lastFrameNumber*/) { ATRACE_CALL(); ALOGV("%s: E", __FUNCTION__); @@ -207,27 +207,29 @@ status_t Camera2Device::capture(CameraMetadata &request) { return OK; } -status_t Camera2Device::captureList(const List<const CameraMetadata> &requests) { +status_t Camera2Device::captureList(const List<const CameraMetadata> &requests, + int64_t* /*lastFrameNumber*/) { ATRACE_CALL(); ALOGE("%s: Camera2Device burst capture not implemented", __FUNCTION__); return INVALID_OPERATION; } - -status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) { +status_t Camera2Device::setStreamingRequest(const CameraMetadata &request, + int64_t* /*lastFrameNumber*/) { ATRACE_CALL(); ALOGV("%s: E", __FUNCTION__); CameraMetadata streamRequest(request); return mRequestQueue.setStreamSlot(streamRequest.release()); } -status_t Camera2Device::setStreamingRequestList(const List<const CameraMetadata> &requests) { +status_t Camera2Device::setStreamingRequestList(const List<const CameraMetadata> &requests, + int64_t* /*lastFrameNumber*/) { ATRACE_CALL(); ALOGE("%s, Camera2Device streaming burst not implemented", __FUNCTION__); return INVALID_OPERATION; } -status_t Camera2Device::clearStreamingRequest() { +status_t Camera2Device::clearStreamingRequest(int64_t* /*lastFrameNumber*/) { ATRACE_CALL(); return mRequestQueue.setStreamSlot(NULL); } @@ -460,7 +462,13 @@ void Camera2Device::notificationCallback(int32_t msg_type, if (listener != NULL) { switch (msg_type) { case CAMERA2_MSG_ERROR: - listener->notifyError(ext1, ext2, ext3); + // TODO: This needs to be fixed. ext2 and ext3 need to be considered. + listener->notifyError( + ((ext1 == CAMERA2_MSG_ERROR_DEVICE) + || (ext1 == CAMERA2_MSG_ERROR_HARDWARE)) ? + ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE : + ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, + CaptureResultExtras()); break; case CAMERA2_MSG_SHUTTER: { // TODO: Only needed for camera2 API, which is unsupported @@ -489,16 +497,22 @@ status_t Camera2Device::waitForNextFrame(nsecs_t timeout) { return mFrameQueue.waitForBuffer(timeout); } -status_t Camera2Device::getNextFrame(CameraMetadata *frame) { +status_t Camera2Device::getNextResult(CaptureResult *result) { ATRACE_CALL(); + ALOGV("%s: get CaptureResult", __FUNCTION__); + if (result == NULL) { + ALOGE("%s: result pointer is NULL", __FUNCTION__); + return BAD_VALUE; + } status_t res; camera_metadata_t *rawFrame; res = mFrameQueue.dequeue(&rawFrame); - if (rawFrame == NULL) { + if (rawFrame == NULL) { return NOT_ENOUGH_DATA; } else if (res == OK) { - frame->acquire(rawFrame); + result->mMetadata.acquire(rawFrame); } + return res; } @@ -568,7 +582,7 @@ status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId, return res; } -status_t Camera2Device::flush() { +status_t Camera2Device::flush(int64_t* /*lastFrameNumber*/) { ATRACE_CALL(); mRequestQueue.clear(); diff --git a/services/camera/libcameraservice/device2/Camera2Device.h b/services/camera/libcameraservice/device2/Camera2Device.h index 61bfd1a..22a13ac 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.h +++ b/services/camera/libcameraservice/device2/Camera2Device.h @@ -47,11 +47,14 @@ class Camera2Device: public CameraDeviceBase { virtual status_t disconnect(); virtual status_t dump(int fd, const Vector<String16>& args); virtual const CameraMetadata& info() const; - virtual status_t capture(CameraMetadata &request); - virtual status_t captureList(const List<const CameraMetadata> &requests); - virtual status_t setStreamingRequest(const CameraMetadata &request); - virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests); - virtual status_t clearStreamingRequest(); + virtual status_t capture(CameraMetadata &request, int64_t *lastFrameNumber = NULL); + virtual status_t captureList(const List<const CameraMetadata> &requests, + int64_t *lastFrameNumber = NULL); + virtual status_t setStreamingRequest(const CameraMetadata &request, + int64_t *lastFrameNumber = NULL); + virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests, + int64_t *lastFrameNumber = NULL); + virtual status_t clearStreamingRequest(int64_t *lastFrameNumber = NULL); virtual status_t waitUntilRequestReceived(int32_t requestId, nsecs_t timeout); virtual status_t createStream(sp<ANativeWindow> consumer, uint32_t width, uint32_t height, int format, size_t size, @@ -67,14 +70,14 @@ class Camera2Device: public CameraDeviceBase { virtual status_t setNotifyCallback(NotificationListener *listener); virtual bool willNotify3A(); virtual status_t waitForNextFrame(nsecs_t timeout); - virtual status_t getNextFrame(CameraMetadata *frame); + virtual status_t getNextResult(CaptureResult *frame); virtual status_t triggerAutofocus(uint32_t id); virtual status_t triggerCancelAutofocus(uint32_t id); virtual status_t triggerPrecaptureMetering(uint32_t id); virtual status_t pushReprocessBuffer(int reprocessStreamId, buffer_handle_t *buffer, wp<BufferReleasedListener> listener); // Flush implemented as just a wait - virtual status_t flush(); + virtual status_t flush(int64_t *lastFrameNumber = NULL); private: const int mId; camera2_device_t *mHal2Device; diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index f586e75..a64917d 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -399,6 +399,7 @@ status_t Camera3Device::convertMetadataListToRequestListLocked( return BAD_VALUE; } + int32_t burstId = 0; for (List<const CameraMetadata>::const_iterator it = metadataList.begin(); it != metadataList.end(); ++it) { sp<CaptureRequest> newRequest = setUpRequestLocked(*it); @@ -406,12 +407,29 @@ status_t Camera3Device::convertMetadataListToRequestListLocked( CLOGE("Can't create capture request"); return BAD_VALUE; } + + // Setup burst Id and request Id + newRequest->mResultExtras.burstId = burstId++; + if (it->exists(ANDROID_REQUEST_ID)) { + if (it->find(ANDROID_REQUEST_ID).count == 0) { + CLOGE("RequestID entry exists; but must not be empty in metadata"); + return BAD_VALUE; + } + newRequest->mResultExtras.requestId = it->find(ANDROID_REQUEST_ID).data.i32[0]; + } else { + CLOGE("RequestID does not exist in metadata"); + return BAD_VALUE; + } + requestList->push_back(newRequest); + if (newRequest->mResultExtras.requestId > 0) { + ALOGV("%s: requestId = %" PRId32, __FUNCTION__, newRequest->mResultExtras.requestId); + } } return OK; } -status_t Camera3Device::capture(CameraMetadata &request) { +status_t Camera3Device::capture(CameraMetadata &request, int64_t* /*lastFrameNumber*/) { ATRACE_CALL(); status_t res; Mutex::Autolock il(mInterfaceLock); @@ -459,7 +477,7 @@ status_t Camera3Device::capture(CameraMetadata &request) { } status_t Camera3Device::submitRequestsHelper( - const List<const CameraMetadata> &requests, bool repeating) { + const List<const CameraMetadata> &requests, bool repeating, int64_t *lastFrameNumber) { ATRACE_CALL(); Mutex::Autolock il(mInterfaceLock); Mutex::Autolock l(mLock); @@ -479,9 +497,15 @@ status_t Camera3Device::submitRequestsHelper( } if (repeating) { + if (lastFrameNumber != NULL) { + *lastFrameNumber = mRequestThread->getLastFrameNumber(); + } res = mRequestThread->setRepeatingRequests(requestList); } else { res = mRequestThread->queueRequestList(requestList); + if (lastFrameNumber != NULL) { + *lastFrameNumber = mRequestThread->getLastFrameNumber(); + } } if (res == OK) { @@ -499,13 +523,15 @@ status_t Camera3Device::submitRequestsHelper( return res; } -status_t Camera3Device::captureList(const List<const CameraMetadata> &requests) { +status_t Camera3Device::captureList(const List<const CameraMetadata> &requests, + int64_t *lastFrameNumber) { ATRACE_CALL(); - return submitRequestsHelper(requests, /*repeating*/false); + return submitRequestsHelper(requests, /*repeating*/false, lastFrameNumber); } -status_t Camera3Device::setStreamingRequest(const CameraMetadata &request) { +status_t Camera3Device::setStreamingRequest(const CameraMetadata &request, + int64_t* /*lastFrameNumber*/) { ATRACE_CALL(); status_t res; Mutex::Autolock il(mInterfaceLock); @@ -550,10 +576,11 @@ status_t Camera3Device::setStreamingRequest(const CameraMetadata &request) { return res; } -status_t Camera3Device::setStreamingRequestList(const List<const CameraMetadata> &requests) { +status_t Camera3Device::setStreamingRequestList(const List<const CameraMetadata> &requests, + int64_t *lastFrameNumber) { ATRACE_CALL(); - return submitRequestsHelper(requests, /*repeating*/true); + return submitRequestsHelper(requests, /*repeating*/true, lastFrameNumber); } sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked( @@ -576,7 +603,7 @@ sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked( return newRequest; } -status_t Camera3Device::clearStreamingRequest() { +status_t Camera3Device::clearStreamingRequest(int64_t *lastFrameNumber) { ATRACE_CALL(); Mutex::Autolock il(mInterfaceLock); Mutex::Autolock l(mLock); @@ -598,6 +625,13 @@ status_t Camera3Device::clearStreamingRequest() { return INVALID_OPERATION; } ALOGV("Camera %d: Clearing repeating request", mId); + + if (lastFrameNumber != NULL) { + *lastFrameNumber = mRequestThread->getLastFrameNumber(); + ALOGV("%s: lastFrameNumber address %p, value %" PRId64, __FUNCTION__, lastFrameNumber, + *lastFrameNumber); + } + return mRequestThread->clearRepeatingRequests(); } @@ -1115,7 +1149,7 @@ status_t Camera3Device::waitForNextFrame(nsecs_t timeout) { return OK; } -status_t Camera3Device::getNextFrame(CameraMetadata *frame) { +status_t Camera3Device::getNextResult(CaptureResult *frame) { ATRACE_CALL(); Mutex::Autolock l(mOutputLock); @@ -1123,8 +1157,14 @@ status_t Camera3Device::getNextFrame(CameraMetadata *frame) { return NOT_ENOUGH_DATA; } - CameraMetadata &result = *(mResultQueue.begin()); - frame->acquire(result); + if (frame == NULL) { + ALOGE("%s: argument cannot be NULL", __FUNCTION__); + return BAD_VALUE; + } + + CaptureResult &result = *(mResultQueue.begin()); + frame->mResultExtras = result.mResultExtras; + frame->mMetadata.acquire(result.mMetadata); mResultQueue.erase(mResultQueue.begin()); return OK; @@ -1202,12 +1242,16 @@ status_t Camera3Device::pushReprocessBuffer(int reprocessStreamId, return INVALID_OPERATION; } -status_t Camera3Device::flush() { +status_t Camera3Device::flush(int64_t *frameNumber) { ATRACE_CALL(); ALOGV("%s: Camera %d: Flushing all requests", __FUNCTION__, mId); Mutex::Autolock il(mInterfaceLock); Mutex::Autolock l(mLock); + if (frameNumber != NULL) { + *frameNumber = mRequestThread->getLastFrameNumber(); + } + mRequestThread->clear(); status_t res; if (mHal3Device->common.version >= CAMERA_DEVICE_API_VERSION_3_1) { @@ -1484,13 +1528,13 @@ void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) { * In-flight request management */ -status_t Camera3Device::registerInFlight(int32_t frameNumber, - int32_t requestId, int32_t numBuffers) { +status_t Camera3Device::registerInFlight(uint32_t frameNumber, + int32_t numBuffers, CaptureResultExtras resultExtras) { ATRACE_CALL(); Mutex::Autolock l(mInFlightLock); ssize_t res; - res = mInFlightMap.add(frameNumber, InFlightRequest(requestId, numBuffers)); + res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras)); if (res < 0) return res; return OK; @@ -1502,8 +1546,8 @@ status_t Camera3Device::registerInFlight(int32_t frameNumber, * to the output frame queue */ bool Camera3Device::processPartial3AQuirk( - int32_t frameNumber, int32_t requestId, - const CameraMetadata& partial) { + uint32_t frameNumber, + const CameraMetadata& partial, const CaptureResultExtras& resultExtras) { // Check if all 3A states are present // The full list of fields is @@ -1567,58 +1611,63 @@ bool Camera3Device::processPartial3AQuirk( Mutex::Autolock l(mOutputLock); - CameraMetadata& min3AResult = - *mResultQueue.insert( - mResultQueue.end(), - CameraMetadata(kMinimal3AResultEntries, /*dataCapacity*/ 0)); - - if (!insert3AResult(min3AResult, ANDROID_REQUEST_FRAME_COUNT, - &frameNumber, frameNumber)) { + CaptureResult captureResult; + captureResult.mResultExtras = resultExtras; + captureResult.mMetadata = CameraMetadata(kMinimal3AResultEntries, /*dataCapacity*/ 0); + // TODO: change this to sp<CaptureResult>. This will need other changes, including, + // but not limited to CameraDeviceBase::getNextResult + CaptureResult& min3AResult = + *mResultQueue.insert(mResultQueue.end(), captureResult); + + if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_FRAME_COUNT, + // TODO: This is problematic casting. Need to fix CameraMetadata. + reinterpret_cast<int32_t*>(&frameNumber), frameNumber)) { return false; } - if (!insert3AResult(min3AResult, ANDROID_REQUEST_ID, + int32_t requestId = resultExtras.requestId; + if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_ID, &requestId, frameNumber)) { return false; } static const uint8_t partialResult = ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL; - if (!insert3AResult(min3AResult, ANDROID_QUIRKS_PARTIAL_RESULT, + if (!insert3AResult(min3AResult.mMetadata, ANDROID_QUIRKS_PARTIAL_RESULT, &partialResult, frameNumber)) { return false; } - if (!insert3AResult(min3AResult, ANDROID_CONTROL_AF_MODE, + if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_MODE, &afMode, frameNumber)) { return false; } - if (!insert3AResult(min3AResult, ANDROID_CONTROL_AWB_MODE, + if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_MODE, &awbMode, frameNumber)) { return false; } - if (!insert3AResult(min3AResult, ANDROID_CONTROL_AE_STATE, + if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_STATE, &aeState, frameNumber)) { return false; } - if (!insert3AResult(min3AResult, ANDROID_CONTROL_AF_STATE, + if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_STATE, &afState, frameNumber)) { return false; } - if (!insert3AResult(min3AResult, ANDROID_CONTROL_AWB_STATE, + if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_STATE, &awbState, frameNumber)) { return false; } - if (!insert3AResult(min3AResult, ANDROID_CONTROL_AF_TRIGGER_ID, + if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_TRIGGER_ID, &afTriggerId, frameNumber)) { return false; } - if (!insert3AResult(min3AResult, ANDROID_CONTROL_AE_PRECAPTURE_ID, + if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_PRECAPTURE_ID, &aeTriggerId, frameNumber)) { return false; } @@ -1630,7 +1679,7 @@ bool Camera3Device::processPartial3AQuirk( template<typename T> bool Camera3Device::get3AResult(const CameraMetadata& result, int32_t tag, - T* value, int32_t frameNumber) { + T* value, uint32_t frameNumber) { (void) frameNumber; camera_metadata_ro_entry_t entry; @@ -1655,7 +1704,7 @@ bool Camera3Device::get3AResult(const CameraMetadata& result, int32_t tag, template<typename T> bool Camera3Device::insert3AResult(CameraMetadata& result, int32_t tag, - const T* value, int32_t frameNumber) { + const T* value, uint32_t frameNumber) { if (result.update(tag, value, 1) != NO_ERROR) { mResultQueue.erase(--mResultQueue.end(), mResultQueue.end()); SET_ERR("Frame %d: Failed to set %s in partial metadata", @@ -1682,11 +1731,12 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { } bool partialResultQuirk = false; CameraMetadata collectedQuirkResult; + CaptureResultExtras resultExtras; - // Get capture timestamp from list of in-flight requests, where it was added - // by the shutter notification for this frame. Then update the in-flight - // status and remove the in-flight entry if all result data has been - // received. + // Get capture timestamp and resultExtras from list of in-flight requests, + // where it was added by the shutter notification for this frame. + // Then update the in-flight status and remove the in-flight entry if + // all result data has been received. nsecs_t timestamp = 0; { Mutex::Autolock l(mInFlightLock); @@ -1697,6 +1747,10 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { return; } InFlightRequest &request = mInFlightMap.editValueAt(idx); + ALOGVV("%s: got InFlightRequest requestId = %" PRId32 ", frameNumber = %" PRId64 + ", burstId = %" PRId32, + __FUNCTION__, request.resultExtras.requestId, request.resultExtras.frameNumber, + request.resultExtras.burstId); // Check if this result carries only partial metadata if (mUsePartialResultQuirk && result->result != NULL) { @@ -1718,13 +1772,17 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { if (!request.partialResultQuirk.haveSent3A) { request.partialResultQuirk.haveSent3A = processPartial3AQuirk(frameNumber, - request.requestId, - request.partialResultQuirk.collectedResult); + request.partialResultQuirk.collectedResult, + request.resultExtras); } } } timestamp = request.captureTimestamp; + resultExtras = request.resultExtras; + ALOGVV("%s: after checking partial burstId = %d, frameNumber %lld", __FUNCTION__, + request.resultExtras.burstId, request.resultExtras.frameNumber); + /** * One of the following must happen before it's legal to call process_capture_result, * unless partial metadata is being provided: @@ -1791,11 +1849,12 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { } mNextResultFrameNumber++; - CameraMetadata captureResult; - captureResult = result->result; + CaptureResult captureResult; + captureResult.mResultExtras = resultExtras; + captureResult.mMetadata = result->result; - if (captureResult.update(ANDROID_REQUEST_FRAME_COUNT, - (int32_t*)&frameNumber, 1) != OK) { + if (captureResult.mMetadata.update(ANDROID_REQUEST_FRAME_COUNT, + (int32_t*)&frameNumber, 1) != OK) { SET_ERR("Failed to set frame# in metadata (%d)", frameNumber); gotResult = false; @@ -1806,15 +1865,15 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { // Append any previous partials to form a complete result if (mUsePartialResultQuirk && !collectedQuirkResult.isEmpty()) { - captureResult.append(collectedQuirkResult); + captureResult.mMetadata.append(collectedQuirkResult); } - captureResult.sort(); + captureResult.mMetadata.sort(); // Check that there's a timestamp in the result metadata camera_metadata_entry entry = - captureResult.find(ANDROID_SENSOR_TIMESTAMP); + captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP); if (entry.count == 0) { SET_ERR("No timestamp provided by HAL for frame %d!", frameNumber); @@ -1828,9 +1887,13 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { if (gotResult) { // Valid result, insert into queue - CameraMetadata& queuedResult = - *mResultQueue.insert(mResultQueue.end(), CameraMetadata()); - queuedResult.swap(captureResult); + List<CaptureResult>::iterator queuedResult = + mResultQueue.insert(mResultQueue.end(), CaptureResult(captureResult)); + ALOGVV("%s: result requestId = %" PRId32 ", frameNumber = %" PRId64 + ", burstId = %" PRId32, __FUNCTION__, + queuedResult->mResultExtras.requestId, + queuedResult->mResultExtras.frameNumber, + queuedResult->mResultExtras.burstId); } } // scope for mOutputLock @@ -1856,8 +1919,6 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { } - - void Camera3Device::notify(const camera3_notify_msg *msg) { ATRACE_CALL(); NotificationListener *listener; @@ -1884,18 +1945,32 @@ void Camera3Device::notify(const camera3_notify_msg *msg) { mId, __FUNCTION__, msg->message.error.frame_number, streamId, msg->message.error.error_code); + CaptureResultExtras resultExtras; // Set request error status for the request in the in-flight tracking { Mutex::Autolock l(mInFlightLock); ssize_t idx = mInFlightMap.indexOfKey(msg->message.error.frame_number); if (idx >= 0) { - mInFlightMap.editValueAt(idx).requestStatus = msg->message.error.error_code; + InFlightRequest &r = mInFlightMap.editValueAt(idx); + r.requestStatus = msg->message.error.error_code; + resultExtras = r.resultExtras; + } else { + resultExtras.frameNumber = msg->message.error.frame_number; + ALOGE("Camera %d: %s: cannot find in-flight request on frame %" PRId64 + " error", mId, __FUNCTION__, resultExtras.frameNumber); } } if (listener != NULL) { - listener->notifyError(msg->message.error.error_code, - msg->message.error.frame_number, streamId); + if (msg->message.error.error_code == CAMERA3_MSG_ERROR_DEVICE) { + listener->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE, + resultExtras); + } else { + listener->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, + resultExtras); + } + } else { + ALOGE("Camera %d: %s: no listener available", mId, __FUNCTION__); } break; } @@ -1915,7 +1990,7 @@ void Camera3Device::notify(const camera3_notify_msg *msg) { mNextShutterFrameNumber++; } - int32_t requestId = -1; + CaptureResultExtras resultExtras; // Set timestamp for the request in the in-flight tracking // and get the request ID to send upstream @@ -1925,7 +2000,7 @@ void Camera3Device::notify(const camera3_notify_msg *msg) { if (idx >= 0) { InFlightRequest &r = mInFlightMap.editValueAt(idx); r.captureTimestamp = timestamp; - requestId = r.requestId; + resultExtras = r.resultExtras; } } if (idx < 0) { @@ -1934,10 +2009,10 @@ void Camera3Device::notify(const camera3_notify_msg *msg) { break; } ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %" PRId64, - mId, __FUNCTION__, frameNumber, requestId, timestamp); + mId, __FUNCTION__, frameNumber, resultExtras.requestId, timestamp); // Call listener, if any if (listener != NULL) { - listener->notifyShutter(requestId, timestamp); + listener->notifyShutter(resultExtras, timestamp); } break; } @@ -1959,6 +2034,7 @@ CameraMetadata Camera3Device::getLatestRequestLocked() { return retVal; } + /** * RequestThread inner class methods */ @@ -1975,7 +2051,8 @@ Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent, mDoPause(false), mPaused(true), mFrameNumber(0), - mLatestRequestId(NAME_NOT_FOUND) { + mLatestRequestId(NAME_NOT_FOUND), + mLastFrameNumber(-1) { mStatusId = statusTracker->addComponent(); } @@ -1989,6 +2066,8 @@ status_t Camera3Device::RequestThread::queueRequest( Mutex::Autolock l(mRequestLock); mRequestQueue.push_back(request); + mLastFrameNumber++; + unpauseForNewRequests(); return OK; @@ -2002,6 +2081,8 @@ status_t Camera3Device::RequestThread::queueRequestList( mRequestQueue.push_back(*it); } + mLastFrameNumber += requests.size(); + unpauseForNewRequests(); return OK; @@ -2086,6 +2167,7 @@ status_t Camera3Device::RequestThread::clear() { mRepeatingRequests.clear(); mRequestQueue.clear(); mTriggerMap.clear(); + // Question: no need to reset frame number? return OK; } @@ -2242,6 +2324,8 @@ bool Camera3Device::RequestThread::threadLoop() { } request.frame_number = mFrameNumber++; + // Update frameNumber of CaptureResultExtras + nextRequest->mResultExtras.frameNumber = request.frame_number; // Log request in the in-flight queue sp<Camera3Device> parent = mParent.promote(); @@ -2251,8 +2335,12 @@ bool Camera3Device::RequestThread::threadLoop() { return false; } - res = parent->registerInFlight(request.frame_number, requestId, - request.num_output_buffers); + res = parent->registerInFlight(request.frame_number, + request.num_output_buffers, nextRequest->mResultExtras); + ALOGVV("%s: registered in flight requestId = %d, frameNumber = %lld, burstId = %d ", + __FUNCTION__, + nextRequest->mResultExtras.requestId, nextRequest->mResultExtras.frameNumber, + nextRequest->mResultExtras.burstId); if (res != OK) { SET_ERR("RequestThread: Unable to register new in-flight request:" " %s (%d)", strerror(-res), res); @@ -2329,6 +2417,14 @@ CameraMetadata Camera3Device::RequestThread::getLatestRequest() const { return mLatestRequest; } +int64_t Camera3Device::RequestThread::getLastFrameNumber() { + Mutex::Autolock al(mRequestLock); + + ALOGV("RequestThread::%s", __FUNCTION__); + + return mLastFrameNumber; +} + void Camera3Device::RequestThread::cleanUpFailedRequest( camera3_capture_request_t &request, sp<CaptureRequest> &nextRequest, @@ -2370,6 +2466,9 @@ sp<Camera3Device::CaptureRequest> ++firstRequest, requests.end()); // No need to wait any longer + + mLastFrameNumber += requests.size(); + break; } diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h index ed58246..b1ea5ed 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.h +++ b/services/camera/libcameraservice/device3/Camera3Device.h @@ -24,6 +24,7 @@ #include <utils/Thread.h> #include <utils/KeyedVector.h> #include <hardware/camera3.h> +#include <camera/CaptureResult.h> #include "common/CameraDeviceBase.h" #include "device3/StatusTracker.h" @@ -78,11 +79,14 @@ class Camera3Device : // Capture and setStreamingRequest will configure streams if currently in // idle state - virtual status_t capture(CameraMetadata &request); - virtual status_t captureList(const List<const CameraMetadata> &requests); - virtual status_t setStreamingRequest(const CameraMetadata &request); - virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests); - virtual status_t clearStreamingRequest(); + virtual status_t capture(CameraMetadata &request, int64_t *lastFrameNumber = NULL); + virtual status_t captureList(const List<const CameraMetadata> &requests, + int64_t *lastFrameNumber = NULL); + virtual status_t setStreamingRequest(const CameraMetadata &request, + int64_t *lastFrameNumber = NULL); + virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests, + int64_t *lastFrameNumber = NULL); + virtual status_t clearStreamingRequest(int64_t *lastFrameNumber = NULL); virtual status_t waitUntilRequestReceived(int32_t requestId, nsecs_t timeout); @@ -118,7 +122,7 @@ class Camera3Device : virtual status_t setNotifyCallback(NotificationListener *listener); virtual bool willNotify3A(); virtual status_t waitForNextFrame(nsecs_t timeout); - virtual status_t getNextFrame(CameraMetadata *frame); + virtual status_t getNextResult(CaptureResult *frame); virtual status_t triggerAutofocus(uint32_t id); virtual status_t triggerCancelAutofocus(uint32_t id); @@ -127,7 +131,7 @@ class Camera3Device : virtual status_t pushReprocessBuffer(int reprocessStreamId, buffer_handle_t *buffer, wp<BufferReleasedListener> listener); - virtual status_t flush(); + virtual status_t flush(int64_t *lastFrameNumber = NULL); // Methods called by subclasses void notifyStatus(bool idle); // updates from StatusTracker @@ -200,6 +204,7 @@ class Camera3Device : sp<camera3::Camera3Stream> mInputStream; Vector<sp<camera3::Camera3OutputStreamInterface> > mOutputStreams; + CaptureResultExtras mResultExtras; }; typedef List<sp<CaptureRequest> > RequestList; @@ -209,7 +214,8 @@ class Camera3Device : const List<const CameraMetadata> &metadataList, /*out*/RequestList *requestList); - status_t submitRequestsHelper(const List<const CameraMetadata> &requests, bool repeating); + status_t submitRequestsHelper(const List<const CameraMetadata> &requests, bool repeating, + int64_t *lastFrameNumber = NULL); /** * Get the last request submitted to the hal by the request thread. @@ -371,6 +377,8 @@ class Camera3Device : */ CameraMetadata getLatestRequest() const; + int64_t getLastFrameNumber(); + protected: virtual bool threadLoop(); @@ -447,6 +455,8 @@ class Camera3Device : TriggerMap mTriggerMap; TriggerMap mTriggerRemovedMap; TriggerMap mTriggerReplacedMap; + + int64_t mLastFrameNumber; }; sp<RequestThread> mRequestThread; @@ -455,8 +465,6 @@ class Camera3Device : */ struct InFlightRequest { - // android.request.id for the request - int requestId; // Set by notify() SHUTTER call. nsecs_t captureTimestamp; int requestStatus; @@ -465,6 +473,7 @@ class Camera3Device : // Decremented by calls to process_capture_result with valid output // buffers int numBuffersLeft; + CaptureResultExtras resultExtras; // Fields used by the partial result quirk only struct PartialResultQuirkInFlight { @@ -480,20 +489,26 @@ class Camera3Device : // Default constructor needed by KeyedVector InFlightRequest() : - requestId(0), captureTimestamp(0), requestStatus(OK), haveResultMetadata(false), numBuffersLeft(0) { } - InFlightRequest(int id, int numBuffers) : - requestId(id), + InFlightRequest(int numBuffers) : captureTimestamp(0), requestStatus(OK), haveResultMetadata(false), numBuffersLeft(numBuffers) { } + + InFlightRequest(int numBuffers, CaptureResultExtras extras) : + captureTimestamp(0), + requestStatus(OK), + haveResultMetadata(false), + numBuffersLeft(numBuffers), + resultExtras(extras) { + } }; // Map from frame number to the in-flight request state typedef KeyedVector<uint32_t, InFlightRequest> InFlightMap; @@ -501,25 +516,25 @@ class Camera3Device : Mutex mInFlightLock; // Protects mInFlightMap InFlightMap mInFlightMap; - status_t registerInFlight(int32_t frameNumber, int32_t requestId, - int32_t numBuffers); + status_t registerInFlight(uint32_t frameNumber, + int32_t numBuffers, CaptureResultExtras resultExtras); /** * For the partial result quirk, check if all 3A state fields are available * and if so, queue up 3A-only result to the client. Returns true if 3A * is sent. */ - bool processPartial3AQuirk(int32_t frameNumber, int32_t requestId, - const CameraMetadata& partial); + bool processPartial3AQuirk(uint32_t frameNumber, + const CameraMetadata& partial, const CaptureResultExtras& resultExtras); // Helpers for reading and writing 3A metadata into to/from partial results template<typename T> bool get3AResult(const CameraMetadata& result, int32_t tag, - T* value, int32_t frameNumber); + T* value, uint32_t frameNumber); template<typename T> bool insert3AResult(CameraMetadata &result, int32_t tag, const T* value, - int32_t frameNumber); + uint32_t frameNumber); /** * Tracking for idle detection */ @@ -536,7 +551,7 @@ class Camera3Device : uint32_t mNextResultFrameNumber; uint32_t mNextShutterFrameNumber; - List<CameraMetadata> mResultQueue; + List<CaptureResult> mResultQueue; Condition mResultSignal; NotificationListener *mListener; |