From 6551e1ede59f4a3043fb141159ca67bd2c85a911 Mon Sep 17 00:00:00 2001 From: Ruben Brunk Date: Tue, 9 Sep 2014 16:20:53 -0700 Subject: [PATCH] camera2: Fix video snapshot for HAL 2.* devices. Bug: 15408128 - Lazily destroy ZSL stream when ZslProcessor is updated, or when the camera client is disconnected, allowing HAL 2.* devices that rely on the ZSL stream to capture video snapshots to function correctly. Change-Id: Ia5cf14c62acda4d9c640440dc5b8e0796dc0b3fa --- services/camera/libcameraservice/Android.mk | 1 + .../camera/libcameraservice/api1/Camera2Client.cpp | 3 +++ .../libcameraservice/api1/client2/ZslProcessor.cpp | 15 ++++++++++-- .../libcameraservice/api1/client2/ZslProcessor.h | 3 +++ .../api1/client2/ZslProcessorInterface.cpp | 28 ++++++++++++++++++++++ .../api1/client2/ZslProcessorInterface.h | 5 ++++ 6 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 services/camera/libcameraservice/api1/client2/ZslProcessorInterface.cpp diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk index 9d6ab23951..e184d97a41 100644 --- a/services/camera/libcameraservice/Android.mk +++ b/services/camera/libcameraservice/Android.mk @@ -34,6 +34,7 @@ LOCAL_SRC_FILES:= \ api1/client2/JpegProcessor.cpp \ api1/client2/CallbackProcessor.cpp \ api1/client2/ZslProcessor.cpp \ + api1/client2/ZslProcessorInterface.cpp \ api1/client2/BurstCapture.cpp \ api1/client2/JpegCompressor.cpp \ api1/client2/CaptureSequencer.cpp \ diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp index bc4097184f..40c8e5d866 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.cpp +++ b/services/camera/libcameraservice/api1/Camera2Client.cpp @@ -434,6 +434,9 @@ void Camera2Client::disconnect() { mCallbackProcessor->deleteStream(); mZslProcessor->deleteStream(); + // Remove all ZSL stream state before disconnect; needed to work around b/15408128. + mZslProcessor->disconnect(); + ALOGV("Camera %d: Disconnecting device", mCameraId); mDevice->disconnect(); diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp index 8fb876eed1..bb722067a7 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp @@ -48,6 +48,7 @@ ZslProcessor::ZslProcessor( mDevice(client->getCameraDevice()), mSequencer(sequencer), mId(client->getCameraId()), + mDeleted(false), mZslBufferAvailable(false), mZslStreamId(NO_STREAM), mZslReprocessStreamId(NO_STREAM), @@ -62,7 +63,7 @@ ZslProcessor::ZslProcessor( ZslProcessor::~ZslProcessor() { ALOGV("%s: Exit", __FUNCTION__); - deleteStream(); + disconnect(); } void ZslProcessor::onFrameAvailable() { @@ -153,7 +154,7 @@ status_t ZslProcessor::updateStream(const Parameters ¶ms) { mId, strerror(-res), res); return res; } - if (currentWidth != (uint32_t)params.fastInfo.arrayWidth || + if (mDeleted || currentWidth != (uint32_t)params.fastInfo.arrayWidth || currentHeight != (uint32_t)params.fastInfo.arrayHeight) { res = device->deleteReprocessStream(mZslReprocessStreamId); if (res != OK) { @@ -175,6 +176,8 @@ status_t ZslProcessor::updateStream(const Parameters ¶ms) { } } + mDeleted = false; + if (mZslStreamId == NO_STREAM) { // Create stream for HAL production // TODO: Sort out better way to select resolution for ZSL @@ -209,6 +212,14 @@ status_t ZslProcessor::updateStream(const Parameters ¶ms) { status_t ZslProcessor::deleteStream() { ATRACE_CALL(); + Mutex::Autolock l(mInputMutex); + // WAR(b/15408128): do not delete stream unless client is being disconnected. + mDeleted = true; + return OK; +} + +status_t ZslProcessor::disconnect() { + ATRACE_CALL(); status_t res; Mutex::Autolock l(mInputMutex); diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.h b/services/camera/libcameraservice/api1/client2/ZslProcessor.h index f4cf0c853a..b6533cfc8a 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessor.h +++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.h @@ -67,6 +67,7 @@ class ZslProcessor: status_t updateStream(const Parameters ¶ms); status_t deleteStream(); + status_t disconnect(); int getStreamId() const; status_t pushToReprocess(int32_t requestId); @@ -86,6 +87,8 @@ class ZslProcessor: wp mSequencer; int mId; + bool mDeleted; + mutable Mutex mInputMutex; bool mZslBufferAvailable; Condition mZslBufferAvailableSignal; diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessorInterface.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessorInterface.cpp new file mode 100644 index 0000000000..9efeaba817 --- /dev/null +++ b/services/camera/libcameraservice/api1/client2/ZslProcessorInterface.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2014 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 "ZslProcessorInterface.h" + +namespace android { +namespace camera2 { + +status_t ZslProcessorInterface::disconnect() { + return OK; +} + +}; //namespace camera2 +}; //namespace android + diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessorInterface.h b/services/camera/libcameraservice/api1/client2/ZslProcessorInterface.h index 183c0c25e8..9e266e781f 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessorInterface.h +++ b/services/camera/libcameraservice/api1/client2/ZslProcessorInterface.h @@ -19,6 +19,8 @@ #include #include +#include +#include namespace android { namespace camera2 { @@ -37,6 +39,9 @@ public: // Delete the underlying CameraDevice streams virtual status_t deleteStream() = 0; + // Clear any additional state necessary before the CameraDevice is disconnected + virtual status_t disconnect(); + /** * Submits a ZSL capture request (id = requestId) * -- 2.11.0