diff options
Diffstat (limited to 'services/camera/libcameraservice/camera2')
4 files changed, 50 insertions, 9 deletions
diff --git a/services/camera/libcameraservice/camera2/CallbackProcessor.cpp b/services/camera/libcameraservice/camera2/CallbackProcessor.cpp index 30c14ef..1734c6a 100644 --- a/services/camera/libcameraservice/camera2/CallbackProcessor.cpp +++ b/services/camera/libcameraservice/camera2/CallbackProcessor.cpp @@ -34,6 +34,7 @@ CallbackProcessor::CallbackProcessor(wp<Camera2Client> client): Thread(false), mClient(client), mCallbackAvailable(false), + mCallbackToApp(false), mCallbackStreamId(NO_STREAM) { } @@ -50,6 +51,35 @@ void CallbackProcessor::onFrameAvailable() { } } +status_t CallbackProcessor::setCallbackWindow( + sp<ANativeWindow> callbackWindow) { + ATRACE_CALL(); + status_t res; + + Mutex::Autolock l(mInputMutex); + + sp<Camera2Client> client = mClient.promote(); + if (client == 0) return OK; + sp<CameraDeviceBase> device = client->getCameraDevice(); + + // If the window is changing, clear out stream if it already exists + if (mCallbackWindow != callbackWindow && mCallbackStreamId != NO_STREAM) { + res = device->deleteStream(mCallbackStreamId); + if (res != OK) { + ALOGE("%s: Camera %d: Unable to delete old stream " + "for callbacks: %s (%d)", __FUNCTION__, + client->getCameraId(), strerror(-res), res); + return res; + } + mCallbackStreamId = NO_STREAM; + mCallbackConsumer.clear(); + } + mCallbackWindow = callbackWindow; + mCallbackToApp = (mCallbackWindow != NULL); + + return OK; +} + status_t CallbackProcessor::updateStream(const Parameters ¶ms) { ATRACE_CALL(); status_t res; @@ -60,8 +90,8 @@ status_t CallbackProcessor::updateStream(const Parameters ¶ms) { if (client == 0) return OK; sp<CameraDeviceBase> device = client->getCameraDevice(); - if (mCallbackConsumer == 0) { - // Create CPU buffer queue endpoint + if (!mCallbackToApp && mCallbackConsumer == 0) { + // Create CPU buffer queue endpoint, since app hasn't given us one mCallbackConsumer = new CpuConsumer(kCallbackHeapCount); mCallbackConsumer->setFrameAvailableListener(this); mCallbackConsumer->setName(String8("Camera2Client::CallbackConsumer")); @@ -69,6 +99,9 @@ status_t CallbackProcessor::updateStream(const Parameters ¶ms) { mCallbackConsumer->getProducerInterface()); } + uint32_t targetFormat = mCallbackToApp ? (uint32_t)HAL_PIXEL_FORMAT_YV12 : + (uint32_t)params.previewFormat; + if (mCallbackStreamId != NO_STREAM) { // Check if stream parameters have to change uint32_t currentWidth, currentHeight, currentFormat; @@ -82,17 +115,18 @@ status_t CallbackProcessor::updateStream(const Parameters ¶ms) { } if (currentWidth != (uint32_t)params.previewWidth || currentHeight != (uint32_t)params.previewHeight || - currentFormat != (uint32_t)params.previewFormat) { + currentFormat != targetFormat) { // Since size should only change while preview is not running, // assuming that all existing use of old callback stream is // completed. - ALOGV("%s: Camera %d: Deleting stream %d since the buffer dimensions changed", - __FUNCTION__, client->getCameraId(), mCallbackStreamId); + ALOGV("%s: Camera %d: Deleting stream %d since the buffer" + " dimensions changed", __FUNCTION__, + client->getCameraId(), mCallbackStreamId); res = device->deleteStream(mCallbackStreamId); if (res != OK) { ALOGE("%s: Camera %d: Unable to delete old output stream " - "for callbacks: %s (%d)", __FUNCTION__, client->getCameraId(), - strerror(-res), res); + "for callbacks: %s (%d)", __FUNCTION__, + client->getCameraId(), strerror(-res), res); return res; } mCallbackStreamId = NO_STREAM; @@ -102,10 +136,10 @@ status_t CallbackProcessor::updateStream(const Parameters ¶ms) { if (mCallbackStreamId == NO_STREAM) { ALOGV("Creating callback stream: %d %d format 0x%x", params.previewWidth, params.previewHeight, - params.previewFormat); + targetFormat); res = device->createStream(mCallbackWindow, params.previewWidth, params.previewHeight, - params.previewFormat, 0, &mCallbackStreamId); + targetFormat, 0, &mCallbackStreamId); if (res != OK) { ALOGE("%s: Camera %d: Can't create output stream for callbacks: " "%s (%d)", __FUNCTION__, client->getCameraId(), diff --git a/services/camera/libcameraservice/camera2/CallbackProcessor.h b/services/camera/libcameraservice/camera2/CallbackProcessor.h index e68bb75..5c46e0d 100644 --- a/services/camera/libcameraservice/camera2/CallbackProcessor.h +++ b/services/camera/libcameraservice/camera2/CallbackProcessor.h @@ -44,6 +44,8 @@ class CallbackProcessor: void onFrameAvailable(); + // Set to NULL to disable the direct-to-app callback window + status_t setCallbackWindow(sp<ANativeWindow> callbackWindow); status_t updateStream(const Parameters ¶ms); status_t deleteStream(); int getStreamId() const; @@ -61,6 +63,9 @@ class CallbackProcessor: NO_STREAM = -1 }; + // True if mCallbackWindow is a remote consumer, false if just the local + // mCallbackConsumer + bool mCallbackToApp; int mCallbackStreamId; static const size_t kCallbackHeapCount = 6; sp<CpuConsumer> mCallbackConsumer; diff --git a/services/camera/libcameraservice/camera2/Parameters.cpp b/services/camera/libcameraservice/camera2/Parameters.cpp index d13fe8b..1108535 100644 --- a/services/camera/libcameraservice/camera2/Parameters.cpp +++ b/services/camera/libcameraservice/camera2/Parameters.cpp @@ -787,6 +787,7 @@ status_t Parameters::initialize(const CameraMetadata *info) { previewCallbackFlags = 0; previewCallbackOneShot = false; + previewCallbackSurface = false; char value[PROPERTY_VALUE_MAX]; property_get("camera.disable_zsl_mode", value, "0"); diff --git a/services/camera/libcameraservice/camera2/Parameters.h b/services/camera/libcameraservice/camera2/Parameters.h index fe3ec1d..83743f8 100644 --- a/services/camera/libcameraservice/camera2/Parameters.h +++ b/services/camera/libcameraservice/camera2/Parameters.h @@ -142,6 +142,7 @@ struct Parameters { uint32_t previewCallbackFlags; bool previewCallbackOneShot; + bool previewCallbackSurface; bool zslMode; |