summaryrefslogtreecommitdiffstats
path: root/services/camera
diff options
context:
space:
mode:
Diffstat (limited to 'services/camera')
-rw-r--r--services/camera/libcameraservice/CameraService.cpp19
-rw-r--r--services/camera/libcameraservice/CameraService.h2
-rw-r--r--services/camera/libcameraservice/api1/Camera2Client.cpp10
-rw-r--r--services/camera/libcameraservice/api1/Camera2Client.h2
-rw-r--r--services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp54
-rw-r--r--services/camera/libcameraservice/api1/client2/CaptureSequencer.h9
-rw-r--r--services/camera/libcameraservice/common/CameraModule.cpp30
-rw-r--r--services/camera/libcameraservice/device3/Camera3Device.cpp90
-rw-r--r--services/camera/libcameraservice/device3/Camera3Device.h5
9 files changed, 180 insertions, 41 deletions
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 527e80b..6f073ed 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -33,6 +33,7 @@
#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
#include <binder/ProcessInfoService.h>
+#include <camera/ICameraServiceProxy.h>
#include <cutils/atomic.h>
#include <cutils/properties.h>
#include <gui/Surface.h>
@@ -230,6 +231,18 @@ void CameraService::onFirstRef()
}
CameraDeviceFactory::registerService(this);
+
+ CameraService::pingCameraServiceProxy();
+}
+
+void CameraService::pingCameraServiceProxy() {
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("media.camera.proxy"));
+ if (binder == nullptr) {
+ return;
+ }
+ sp<ICameraServiceProxy> proxyBinder = interface_cast<ICameraServiceProxy>(binder);
+ proxyBinder->pingForUserUpdate();
}
CameraService::~CameraService() {
@@ -992,6 +1005,10 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien
"(PID %" PRId32 ", priority %" PRId32 ")", i->getKey().string(),
String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
i->getPriority());
+ ALOGE(" Conflicts with: Device %s, client package %s (PID %"
+ PRId32 ", priority %" PRId32 ")", i->getKey().string(),
+ String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(),
+ i->getPriority());
}
// Log the client's attempt
@@ -2051,7 +2068,7 @@ String8 CameraService::CameraClientManager::toString() const {
auto conflicting = i->getConflicting();
auto clientSp = i->getValue();
String8 packageName;
- userid_t clientUserId;
+ userid_t clientUserId = 0;
if (clientSp.get() != nullptr) {
packageName = String8{clientSp->getPackageName()};
uid_t clientUid = clientSp->getClientUid();
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 2e4743f..3298772 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -720,6 +720,8 @@ private:
static String8 toString(std::set<userid_t> intSet);
+ static void pingCameraServiceProxy();
+
};
template<class Func>
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 05ede92..f2d6ab2 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -1881,6 +1881,16 @@ void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
mCaptureSequencer->notifyAutoExposure(newState, triggerId);
}
+void Camera2Client::notifyShutter(const CaptureResultExtras& resultExtras,
+ nsecs_t timestamp) {
+ (void)resultExtras;
+ (void)timestamp;
+
+ ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64,
+ __FUNCTION__, resultExtras.requestId, timestamp);
+ mCaptureSequencer->notifyShutter(resultExtras, timestamp);
+}
+
camera2::SharedParameters& Camera2Client::getParameters() {
return mParameters;
}
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index a988037..3784aab 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -106,6 +106,8 @@ public:
virtual void notifyAutoFocus(uint8_t newState, int triggerId);
virtual void notifyAutoExposure(uint8_t newState, int triggerId);
+ virtual void notifyShutter(const CaptureResultExtras& resultExtras,
+ nsecs_t timestamp);
/**
* Interface used by independent components of Camera2Client.
diff --git a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
index 9849f4d..d847e0f 100644
--- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
+++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
@@ -43,6 +43,8 @@ CaptureSequencer::CaptureSequencer(wp<Camera2Client> client):
mNewFrameReceived(false),
mNewCaptureReceived(false),
mShutterNotified(false),
+ mHalNotifiedShutter(false),
+ mShutterCaptureId(-1),
mClient(client),
mCaptureState(IDLE),
mStateTransitionCount(0),
@@ -106,6 +108,16 @@ void CaptureSequencer::notifyAutoExposure(uint8_t newState, int triggerId) {
}
}
+void CaptureSequencer::notifyShutter(const CaptureResultExtras& resultExtras,
+ nsecs_t timestamp) {
+ ATRACE_CALL();
+ Mutex::Autolock l(mInputMutex);
+ if (!mHalNotifiedShutter && resultExtras.requestId == mShutterCaptureId) {
+ mHalNotifiedShutter = true;
+ mShutterNotifySignal.signal();
+ }
+}
+
void CaptureSequencer::onResultAvailable(const CaptureResult &result) {
ATRACE_CALL();
ALOGV("%s: New result available.", __FUNCTION__);
@@ -335,6 +347,11 @@ CaptureSequencer::CaptureState CaptureSequencer::manageStart(
} else {
nextState = STANDARD_START;
}
+ {
+ Mutex::Autolock l(mInputMutex);
+ mShutterCaptureId = mCaptureId;
+ mHalNotifiedShutter = false;
+ }
mShutterNotified = false;
return nextState;
@@ -541,6 +558,7 @@ CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture(
return DONE;
}
}
+
// TODO: Capture should be atomic with setStreamingRequest here
res = client->getCameraDevice()->capture(captureCopy);
if (res != OK) {
@@ -560,6 +578,31 @@ CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
ATRACE_CALL();
Mutex::Autolock l(mInputMutex);
+
+ // Wait for shutter callback
+ while (!mHalNotifiedShutter) {
+ if (mTimeoutCount <= 0) {
+ break;
+ }
+ res = mShutterNotifySignal.waitRelative(mInputMutex, kWaitDuration);
+ if (res == TIMED_OUT) {
+ mTimeoutCount--;
+ return STANDARD_CAPTURE_WAIT;
+ }
+ }
+
+ if (mHalNotifiedShutter) {
+ if (!mShutterNotified) {
+ SharedParameters::Lock l(client->getParameters());
+ /* warning: this also locks a SharedCameraCallbacks */
+ shutterNotifyLocked(l.mParameters, client, mMsgType);
+ mShutterNotified = true;
+ }
+ } else if (mTimeoutCount <= 0) {
+ ALOGW("Timed out waiting for shutter notification");
+ return DONE;
+ }
+
// Wait for new metadata result (mNewFrame)
while (!mNewFrameReceived) {
res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration);
@@ -569,15 +612,6 @@ CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
}
}
- // Approximation of the shutter being closed
- // - TODO: use the hal3 exposure callback in Camera3Device instead
- if (mNewFrameReceived && !mShutterNotified) {
- SharedParameters::Lock l(client->getParameters());
- /* warning: this also locks a SharedCameraCallbacks */
- shutterNotifyLocked(l.mParameters, client, mMsgType);
- mShutterNotified = true;
- }
-
// Wait until jpeg was captured by JpegProcessor
while (mNewFrameReceived && !mNewCaptureReceived) {
res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
@@ -591,6 +625,7 @@ CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
return DONE;
}
if (mNewFrameReceived && mNewCaptureReceived) {
+
if (mNewFrameId != mCaptureId) {
ALOGW("Mismatched capture frame IDs: Expected %d, got %d",
mCaptureId, mNewFrameId);
@@ -667,7 +702,6 @@ CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait(
sp<Camera2Client> &/*client*/) {
status_t res;
ATRACE_CALL();
-
while (!mNewCaptureReceived) {
res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
if (res == TIMED_OUT) {
diff --git a/services/camera/libcameraservice/api1/client2/CaptureSequencer.h b/services/camera/libcameraservice/api1/client2/CaptureSequencer.h
index d42ab13..10252fb 100644
--- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.h
+++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.h
@@ -62,6 +62,10 @@ class CaptureSequencer:
// Notifications about AE state changes
void notifyAutoExposure(uint8_t newState, int triggerId);
+ // Notifications about shutter (capture start)
+ void notifyShutter(const CaptureResultExtras& resultExtras,
+ nsecs_t timestamp);
+
// Notification from the frame processor
virtual void onResultAvailable(const CaptureResult &result);
@@ -95,7 +99,10 @@ class CaptureSequencer:
sp<MemoryBase> mCaptureBuffer;
Condition mNewCaptureSignal;
- bool mShutterNotified;
+ bool mShutterNotified; // Has CaptureSequencer sent shutter to Client
+ bool mHalNotifiedShutter; // Has HAL sent shutter to CaptureSequencer
+ int32_t mShutterCaptureId; // The captureId which is waiting for shutter notification
+ Condition mShutterNotifySignal;
/**
* Internal to CaptureSequencer
diff --git a/services/camera/libcameraservice/common/CameraModule.cpp b/services/camera/libcameraservice/common/CameraModule.cpp
index c662853..2f0117d 100644
--- a/services/camera/libcameraservice/common/CameraModule.cpp
+++ b/services/camera/libcameraservice/common/CameraModule.cpp
@@ -31,7 +31,7 @@ void CameraModule::deriveCameraCharacteristicsKeys(
// Keys added in HAL3.3
if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_3) {
- const size_t NUM_DERIVED_KEYS_HAL3_3 = 3;
+ const size_t NUM_DERIVED_KEYS_HAL3_3 = 5;
Vector<uint8_t> controlModes;
uint8_t data = ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE;
chars.update(ANDROID_CONTROL_AE_LOCK_AVAILABLE, &data, /*count*/1);
@@ -80,6 +80,29 @@ void CameraModule::deriveCameraCharacteristicsKeys(
chars.update(ANDROID_CONTROL_AVAILABLE_MODES, controlModes);
+ entry = chars.find(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
+ // HAL3.2 devices passing existing CTS test should all support all LSC modes and LSC map
+ bool lensShadingModeSupported = false;
+ if (entry.count > 0) {
+ for (size_t i = 0; i < entry.count; i++) {
+ if (entry.data.i32[i] == ANDROID_SHADING_MODE) {
+ lensShadingModeSupported = true;
+ break;
+ }
+ }
+ }
+ Vector<uint8_t> lscModes;
+ Vector<uint8_t> lscMapModes;
+ lscModes.push(ANDROID_SHADING_MODE_FAST);
+ lscModes.push(ANDROID_SHADING_MODE_HIGH_QUALITY);
+ lscMapModes.push(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);
+ if (lensShadingModeSupported) {
+ lscModes.push(ANDROID_SHADING_MODE_OFF);
+ lscMapModes.push(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON);
+ }
+ chars.update(ANDROID_SHADING_AVAILABLE_MODES, lscModes);
+ chars.update(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES, lscMapModes);
+
entry = chars.find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
Vector<int32_t> availableCharsKeys;
availableCharsKeys.setCapacity(entry.count + NUM_DERIVED_KEYS_HAL3_3);
@@ -87,9 +110,12 @@ void CameraModule::deriveCameraCharacteristicsKeys(
availableCharsKeys.push(entry.data.i32[i]);
}
availableCharsKeys.push(ANDROID_CONTROL_AE_LOCK_AVAILABLE);
- availableCharsKeys.push(ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE);
+ availableCharsKeys.push(ANDROID_CONTROL_AWB_LOCK_AVAILABLE);
availableCharsKeys.push(ANDROID_CONTROL_AVAILABLE_MODES);
+ availableCharsKeys.push(ANDROID_SHADING_AVAILABLE_MODES);
+ availableCharsKeys.push(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES);
chars.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, availableCharsKeys);
+
}
return;
}
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 445c9c2..45d9421 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2613,6 +2613,21 @@ status_t Camera3Device::RequestThread::clear(
if (listener != NULL) {
for (RequestList::iterator it = mRequestQueue.begin();
it != mRequestQueue.end(); ++it) {
+ // Abort the input buffers for reprocess requests.
+ if ((*it)->mInputStream != NULL) {
+ camera3_stream_buffer_t inputBuffer;
+ status_t res = (*it)->mInputStream->getInputBuffer(&inputBuffer);
+ if (res != OK) {
+ ALOGW("%s: %d: couldn't get input buffer while clearing the request "
+ "list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
+ } else {
+ res = (*it)->mInputStream->returnInputBuffer(inputBuffer);
+ if (res != OK) {
+ ALOGE("%s: %d: couldn't return input buffer while clearing the request "
+ "list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
+ }
+ }
+ }
// Set the frame number this request would have had, if it
// had been submitted; this frame number will not be reused.
// The requestId and burstId fields were set when the request was
@@ -2752,29 +2767,11 @@ bool Camera3Device::RequestThread::threadLoop() {
__FUNCTION__);
}
- camera3_stream_buffer_t inputBuffer;
uint32_t totalNumBuffers = 0;
// Fill in buffers
-
if (nextRequest->mInputStream != NULL) {
- res = nextRequest->mInputStream->getInputBuffer(&inputBuffer);
- if (res != OK) {
- // Can't get input buffer from gralloc queue - this could be due to
- // disconnected queue or other producer misbehavior, so not a fatal
- // error
- ALOGE("RequestThread: Can't get input buffer, skipping request:"
- " %s (%d)", strerror(-res), res);
- Mutex::Autolock l(mRequestLock);
- if (mListener != NULL) {
- mListener->notifyError(
- ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
- nextRequest->mResultExtras);
- }
- cleanUpFailedRequest(request, nextRequest, outputBuffers);
- return true;
- }
- request.input_buffer = &inputBuffer;
+ request.input_buffer = &nextRequest->mInputBuffer;
totalNumBuffers += 1;
} else {
request.input_buffer = NULL;
@@ -2792,11 +2789,13 @@ bool Camera3Device::RequestThread::threadLoop() {
// error
ALOGE("RequestThread: Can't get output buffer, skipping request:"
" %s (%d)", strerror(-res), res);
- Mutex::Autolock l(mRequestLock);
- if (mListener != NULL) {
- mListener->notifyError(
- ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
- nextRequest->mResultExtras);
+ {
+ Mutex::Autolock l(mRequestLock);
+ if (mListener != NULL) {
+ mListener->notifyError(
+ ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
+ nextRequest->mResultExtras);
+ }
}
cleanUpFailedRequest(request, nextRequest, outputBuffers);
return true;
@@ -2865,6 +2864,12 @@ bool Camera3Device::RequestThread::threadLoop() {
nextRequest->mSettings.unlock(request.settings);
}
+ // Unset as current request
+ {
+ Mutex::Autolock l(mRequestLock);
+ mNextRequest.clear();
+ }
+
// Remove any previously queued triggers (after unlock)
res = removeTriggers(mPrevRequest);
if (res != OK) {
@@ -2890,6 +2895,13 @@ bool Camera3Device::RequestThread::isStreamPending(
sp<Camera3StreamInterface>& stream) {
Mutex::Autolock l(mRequestLock);
+ if (mNextRequest != nullptr) {
+ for (const auto& s : mNextRequest->mOutputStreams) {
+ if (stream == s) return true;
+ }
+ if (stream == mNextRequest->mInputStream) return true;
+ }
+
for (const auto& request : mRequestQueue) {
for (const auto& s : request->mOutputStreams) {
if (stream == s) return true;
@@ -2915,15 +2927,18 @@ void Camera3Device::RequestThread::cleanUpFailedRequest(
if (request.settings != NULL) {
nextRequest->mSettings.unlock(request.settings);
}
- if (request.input_buffer != NULL) {
- request.input_buffer->status = CAMERA3_BUFFER_STATUS_ERROR;
- nextRequest->mInputStream->returnInputBuffer(*(request.input_buffer));
+ if (nextRequest->mInputStream != NULL) {
+ nextRequest->mInputBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
+ nextRequest->mInputStream->returnInputBuffer(nextRequest->mInputBuffer);
}
for (size_t i = 0; i < request.num_output_buffers; i++) {
outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
nextRequest->mOutputStreams.editItemAt(i)->returnBuffer(
outputBuffers[i], 0);
}
+
+ Mutex::Autolock l(mRequestLock);
+ mNextRequest.clear();
}
sp<Camera3Device::CaptureRequest>
@@ -3006,7 +3021,28 @@ sp<Camera3Device::CaptureRequest>
nextRequest->mResultExtras.frameNumber = mFrameNumber++;
nextRequest->mResultExtras.afTriggerId = mCurrentAfTriggerId;
nextRequest->mResultExtras.precaptureTriggerId = mCurrentPreCaptureTriggerId;
+
+ // Since RequestThread::clear() removes buffers from the input stream,
+ // get the right buffer here before unlocking mRequestLock
+ if (nextRequest->mInputStream != NULL) {
+ res = nextRequest->mInputStream->getInputBuffer(&nextRequest->mInputBuffer);
+ if (res != OK) {
+ // Can't get input buffer from gralloc queue - this could be due to
+ // disconnected queue or other producer misbehavior, so not a fatal
+ // error
+ ALOGE("%s: Can't get input buffer, skipping request:"
+ " %s (%d)", __FUNCTION__, strerror(-res), res);
+ if (mListener != NULL) {
+ mListener->notifyError(
+ ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
+ nextRequest->mResultExtras);
+ }
+ return NULL;
+ }
+ }
}
+ mNextRequest = nextRequest;
+
return nextRequest;
}
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 4fbcb2e..b9313fc 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -234,6 +234,7 @@ class Camera3Device :
public:
CameraMetadata mSettings;
sp<camera3::Camera3Stream> mInputStream;
+ camera3_stream_buffer_t mInputBuffer;
Vector<sp<camera3::Camera3OutputStreamInterface> >
mOutputStreams;
CaptureResultExtras mResultExtras;
@@ -501,6 +502,10 @@ class Camera3Device :
Condition mRequestSignal;
RequestList mRequestQueue;
RequestList mRepeatingRequests;
+ // The next request being prepped for submission to the HAL, no longer
+ // on the request queue. Read-only even with mRequestLock held, outside
+ // of threadLoop
+ sp<const CaptureRequest> mNextRequest;
bool mReconfigured;