diff options
Diffstat (limited to 'services/camera')
12 files changed, 259 insertions, 66 deletions
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp index 948b59f..9bcaef1 100644 --- a/services/camera/libcameraservice/Camera2Client.cpp +++ b/services/camera/libcameraservice/Camera2Client.cpp @@ -536,7 +536,7 @@ status_t Camera2Client::setPreviewWindowL(const sp<IBinder>& binder, // Already running preview - need to stop and create a new stream // TODO: Optimize this so that we don't wait for old stream to drain // before spinning up new stream - mDevice->clearStreamingRequest(); + mStreamingProcessor->stopStream(); l.mParameters.state = Parameters::WAITING_FOR_PREVIEW_WINDOW; break; } @@ -719,6 +719,7 @@ void Camera2Client::stopPreview() { void Camera2Client::stopPreviewL() { ATRACE_CALL(); + status_t res; Parameters::State state; { SharedParameters::Lock l(mParameters); @@ -740,6 +741,11 @@ void Camera2Client::stopPreviewL() { // no break - identical to preview case Parameters::PREVIEW: mStreamingProcessor->stopStream(); + res = mDevice->waitUntilDrained(); + if (res != OK) { + ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)", + __FUNCTION__, mCameraId, strerror(-res), res); + } // no break case Parameters::WAITING_FOR_PREVIEW_WINDOW: { SharedParameters::Lock l(mParameters); @@ -946,9 +952,14 @@ status_t Camera2Client::autoFocus() { int triggerId; { SharedParameters::Lock l(mParameters); + if (l.mParameters.state < Parameters::PREVIEW) { + return INVALID_OPERATION; + } + l.mParameters.currentAfTriggerId = ++l.mParameters.afTriggerCounter; triggerId = l.mParameters.currentAfTriggerId; } + syncWithDevice(); mDevice->triggerAutofocus(triggerId); @@ -967,6 +978,7 @@ status_t Camera2Client::cancelAutoFocus() { SharedParameters::Lock l(mParameters); triggerId = ++l.mParameters.afTriggerCounter; } + syncWithDevice(); mDevice->triggerCancelAutofocus(triggerId); @@ -1017,6 +1029,9 @@ status_t Camera2Client::takePicture(int msgType) { return res; } + // Need HAL to have correct settings before (possibly) triggering precapture + syncWithDevice(); + res = mCaptureSequencer->startCapture(); if (res != OK) { ALOGE("%s: Camera %d: Unable to start capture: %s (%d)", @@ -1397,13 +1412,18 @@ int Camera2Client::getZslStreamId() const { return mZslProcessor->getStreamId(); } -status_t Camera2Client::registerFrameListener(int32_t id, +status_t Camera2Client::registerFrameListener(int32_t minId, int32_t maxId, + wp<camera2::FrameProcessor::FilteredListener> listener) { + return mFrameProcessor->registerListener(minId, maxId, listener); +} + +status_t Camera2Client::removeFrameListener(int32_t minId, int32_t maxId, wp<camera2::FrameProcessor::FilteredListener> listener) { - return mFrameProcessor->registerListener(id, listener); + return mFrameProcessor->removeListener(minId, maxId, listener); } -status_t Camera2Client::removeFrameListener(int32_t id) { - return mFrameProcessor->removeListener(id); +status_t Camera2Client::stopStream() { + return mStreamingProcessor->stopStream(); } Camera2Client::SharedCameraClient::Lock::Lock(SharedCameraClient &client): @@ -1432,9 +1452,12 @@ void Camera2Client::SharedCameraClient::clear() { mCameraClient.clear(); } -const int32_t Camera2Client::kPreviewRequestId; -const int32_t Camera2Client::kRecordRequestId; -const int32_t Camera2Client::kFirstCaptureRequestId; +const int32_t Camera2Client::kPreviewRequestIdStart; +const int32_t Camera2Client::kPreviewRequestIdEnd; +const int32_t Camera2Client::kRecordingRequestIdStart; +const int32_t Camera2Client::kRecordingRequestIdEnd; +const int32_t Camera2Client::kCaptureRequestIdStart; +const int32_t Camera2Client::kCaptureRequestIdEnd; /** Utility methods */ @@ -1443,6 +1466,13 @@ status_t Camera2Client::updateRequests(Parameters ¶ms) { ALOGV("%s: Camera %d: state = %d", __FUNCTION__, getCameraId(), params.state); + res = mStreamingProcessor->incrementStreamingIds(); + if (res != OK) { + ALOGE("%s: Camera %d: Unable to increment request IDs: %s (%d)", + __FUNCTION__, mCameraId, strerror(-res), res); + return res; + } + res = mStreamingProcessor->updatePreviewRequest(params); if (res != OK) { ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)", @@ -1504,4 +1534,23 @@ size_t Camera2Client::calculateBufferSize(int width, int height, } } +status_t Camera2Client::syncWithDevice() { + ATRACE_CALL(); + const nsecs_t kMaxSyncTimeout = 100000000; // 100 ms + status_t res; + + int32_t activeRequestId = mStreamingProcessor->getActiveRequestId(); + if (activeRequestId == 0) return OK; + + res = mDevice->waitUntilRequestReceived(activeRequestId, kMaxSyncTimeout); + if (res == TIMED_OUT) { + ALOGE("%s: Camera %d: Timed out waiting sync with HAL", + __FUNCTION__, mCameraId); + } else if (res != OK) { + ALOGE("%s: Camera %d: Error while waiting to sync with HAL", + __FUNCTION__, mCameraId); + } + return res; +} + } // namespace android diff --git a/services/camera/libcameraservice/Camera2Client.h b/services/camera/libcameraservice/Camera2Client.h index fb1dcde..55ead02 100644 --- a/services/camera/libcameraservice/Camera2Client.h +++ b/services/camera/libcameraservice/Camera2Client.h @@ -107,9 +107,12 @@ public: int getRecordingStreamId() const; int getZslStreamId() const; - status_t registerFrameListener(int32_t id, + status_t registerFrameListener(int32_t minId, int32_t maxId, wp<camera2::FrameProcessor::FilteredListener> listener); - status_t removeFrameListener(int32_t id); + status_t removeFrameListener(int32_t minId, int32_t maxId, + wp<camera2::FrameProcessor::FilteredListener> listener); + + status_t stopStream(); // Simple class to ensure that access to ICameraClient is serialized by // requiring mCameraClientLock to be locked before access to mCameraClient @@ -135,9 +138,14 @@ public: static size_t calculateBufferSize(int width, int height, int format, int stride); - static const int32_t kPreviewRequestId = 1000; - static const int32_t kRecordRequestId = 2000; - static const int32_t kFirstCaptureRequestId = 3000; + static const int32_t kPreviewRequestIdStart = 10000000; + static const int32_t kPreviewRequestIdEnd = 20000000; + + static const int32_t kRecordingRequestIdStart = 20000000; + static const int32_t kRecordingRequestIdEnd = 30000000; + + static const int32_t kCaptureRequestIdStart = 30000000; + static const int32_t kCaptureRequestIdEnd = 40000000; private: /** ICamera interface-related private members */ @@ -208,6 +216,9 @@ private: /** Utility members */ + // Wait until the camera device has received the latest control settings + status_t syncWithDevice(); + // Verify that caller is the owner of the camera status_t checkPid(const char *checkLocation) const; }; diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp index 25b7a58..d6445c1 100644 --- a/services/camera/libcameraservice/Camera2Device.cpp +++ b/services/camera/libcameraservice/Camera2Device.cpp @@ -27,6 +27,7 @@ #include <utils/Log.h> #include <utils/Trace.h> +#include <utils/Timers.h> #include "Camera2Device.h" namespace android { @@ -228,6 +229,11 @@ status_t Camera2Device::clearStreamingRequest() { return mRequestQueue.setStreamSlot(NULL); } +status_t Camera2Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) { + ATRACE_CALL(); + return mRequestQueue.waitForDequeue(requestId, timeout); +} + status_t Camera2Device::createStream(sp<ANativeWindow> consumer, uint32_t width, uint32_t height, int format, size_t size, int *id) { ATRACE_CALL(); @@ -567,6 +573,7 @@ Camera2Device::NotificationListener::~NotificationListener() { Camera2Device::MetadataQueue::MetadataQueue(): mDevice(NULL), mFrameCount(0), + mLatestRequestId(0), mCount(0), mStreamSlotCount(0), mSignalConsumer(true) @@ -678,6 +685,16 @@ status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf, mFrameCount++; } + // Check for request ID, and if present, signal waiters. + camera_metadata_entry_t requestId; + res = find_camera_metadata_entry(b, + ANDROID_REQUEST_ID, + &requestId); + if (res == OK) { + mLatestRequestId = requestId.data.i32[0]; + mNewRequestId.signal(); + } + *buf = b; mCount--; @@ -695,6 +712,22 @@ status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout) return OK; } +status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id, + nsecs_t timeout) { + Mutex::Autolock l(mMutex); + status_t res; + while (mLatestRequestId != id) { + nsecs_t startTime = systemTime(); + + res = mNewRequestId.waitRelative(mMutex, timeout); + if (res != OK) return res; + + timeout -= (systemTime() - startTime); + } + + return OK; +} + status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf) { ATRACE_CALL(); diff --git a/services/camera/libcameraservice/Camera2Device.h b/services/camera/libcameraservice/Camera2Device.h index 38662e3..29830bd 100644 --- a/services/camera/libcameraservice/Camera2Device.h +++ b/services/camera/libcameraservice/Camera2Device.h @@ -67,6 +67,13 @@ class Camera2Device : public virtual RefBase { status_t clearStreamingRequest(); /** + * Wait until a request with the given ID has been dequeued by the + * HAL. Returns TIMED_OUT if the timeout duration is reached. Returns + * immediately if the latest request received by the HAL has this id. + */ + status_t waitUntilRequestReceived(int32_t requestId, nsecs_t timeout); + + /** * Create an output stream of the requested size and format. * * If format is CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, then the HAL device selects @@ -226,6 +233,9 @@ class Camera2Device : public virtual RefBase { status_t dequeue(camera_metadata_t **buf, bool incrementCount = true); int getBufferCount(); status_t waitForBuffer(nsecs_t timeout); + // Wait until a buffer with the given ID is dequeued. Will return + // immediately if the latest buffer dequeued has that ID. + status_t waitForDequeue(int32_t id, nsecs_t timeout); // Set repeating buffer(s); if the queue is empty on a dequeue call, the // queue copies the contents of the stream slot into the queue, and then @@ -247,6 +257,8 @@ class Camera2Device : public virtual RefBase { Condition notEmpty; int mFrameCount; + int32_t mLatestRequestId; + Condition mNewRequestId; int mCount; List<camera_metadata_t*> mEntries; diff --git a/services/camera/libcameraservice/camera2/CaptureSequencer.cpp b/services/camera/libcameraservice/camera2/CaptureSequencer.cpp index d56af64..a849246 100644 --- a/services/camera/libcameraservice/camera2/CaptureSequencer.cpp +++ b/services/camera/libcameraservice/camera2/CaptureSequencer.cpp @@ -44,7 +44,7 @@ CaptureSequencer::CaptureSequencer(wp<Camera2Client> client): mCaptureState(IDLE), mTriggerId(0), mTimeoutCount(0), - mCaptureId(Camera2Client::kFirstCaptureRequestId) { + mCaptureId(Camera2Client::kCaptureRequestIdStart) { ALOGV("%s", __FUNCTION__); } @@ -84,12 +84,12 @@ void CaptureSequencer::notifyAutoExposure(uint8_t newState, int triggerId) { } void CaptureSequencer::onFrameAvailable(int32_t frameId, - CameraMetadata &frame) { + const CameraMetadata &frame) { ALOGV("%s: Listener found new frame", __FUNCTION__); ATRACE_CALL(); Mutex::Autolock l(mInputMutex); mNewFrameId = frameId; - mNewFrame.acquire(frame); + mNewFrame = frame; if (!mNewFrameReceived) { mNewFrameReceived = true; mNewFrameSignal.signal(); @@ -203,7 +203,9 @@ CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp<Camera2Client> &c status_t res = OK; ATRACE_CALL(); mCaptureId++; - + if (mCaptureId >= Camera2Client::kCaptureRequestIdEnd) { + mCaptureId = Camera2Client::kCaptureRequestIdStart; + } { Mutex::Autolock l(mInputMutex); mBusy = false; @@ -286,7 +288,7 @@ CaptureSequencer::CaptureState CaptureSequencer::manageZslStart( return DONE; } - client->registerFrameListener(mCaptureId, + client->registerFrameListener(mCaptureId, mCaptureId + 1, this); // TODO: Actually select the right thing here. @@ -326,7 +328,7 @@ CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing( CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart( sp<Camera2Client> &client) { ATRACE_CALL(); - client->registerFrameListener(mCaptureId, + client->registerFrameListener(mCaptureId, mCaptureId + 1, this); { SharedParameters::Lock l(client->getParameters()); @@ -421,7 +423,7 @@ CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture( } if (l.mParameters.state == Parameters::STILL_CAPTURE) { - res = client->getCameraDevice()->clearStreamingRequest(); + res = client->stopStream(); if (res != OK) { ALOGE("%s: Camera %d: Unable to stop preview for still capture: " "%s (%d)", @@ -482,7 +484,7 @@ CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait( ALOGW("Mismatched capture timestamps: Metadata frame %lld," " captured buffer %lld", entry.data.i64[0], mCaptureTimestamp); } - client->removeFrameListener(mCaptureId); + client->removeFrameListener(mCaptureId, mCaptureId + 1, this); mNewFrameReceived = false; mNewCaptureReceived = false; diff --git a/services/camera/libcameraservice/camera2/CaptureSequencer.h b/services/camera/libcameraservice/camera2/CaptureSequencer.h index 27f3f1c..07e4c01 100644 --- a/services/camera/libcameraservice/camera2/CaptureSequencer.h +++ b/services/camera/libcameraservice/camera2/CaptureSequencer.h @@ -57,7 +57,7 @@ class CaptureSequencer: void notifyAutoExposure(uint8_t newState, int triggerId); // Notifications from the frame processor - virtual void onFrameAvailable(int32_t frameId, CameraMetadata &frame); + virtual void onFrameAvailable(int32_t frameId, const CameraMetadata &frame); // Notifications from the JPEG processor void onCaptureAvailable(nsecs_t timestamp, sp<MemoryBase> captureBuffer); diff --git a/services/camera/libcameraservice/camera2/FrameProcessor.cpp b/services/camera/libcameraservice/camera2/FrameProcessor.cpp index 0c8560b..064607c 100644 --- a/services/camera/libcameraservice/camera2/FrameProcessor.cpp +++ b/services/camera/libcameraservice/camera2/FrameProcessor.cpp @@ -36,17 +36,30 @@ FrameProcessor::~FrameProcessor() { ALOGV("%s: Exit", __FUNCTION__); } -status_t FrameProcessor::registerListener(int32_t id, - wp<FilteredListener> listener) { +status_t FrameProcessor::registerListener(int32_t minId, + int32_t maxId, wp<FilteredListener> listener) { Mutex::Autolock l(mInputMutex); - ALOGV("%s: Registering listener for frame id %d", - __FUNCTION__, id); - return mListeners.replaceValueFor(id, listener); + ALOGV("%s: Registering listener for frame id range %d - %d", + __FUNCTION__, minId, maxId); + RangeListener rListener = { minId, maxId, listener }; + mRangeListeners.push_back(rListener); + return OK; } -status_t FrameProcessor::removeListener(int32_t id) { +status_t FrameProcessor::removeListener(int32_t minId, + int32_t maxId, wp<FilteredListener> listener) { Mutex::Autolock l(mInputMutex); - return mListeners.removeItem(id); + List<RangeListener>::iterator item = mRangeListeners.begin(); + while (item != mRangeListeners.end()) { + if (item->minId == minId && + item->maxId == maxId && + item->listener == listener) { + item = mRangeListeners.erase(item); + } else { + item++; + } + } + return OK; } void FrameProcessor::dump(int fd, const Vector<String16>& args) { @@ -97,8 +110,7 @@ void FrameProcessor::processNewFrames(sp<Camera2Client> &client) { res = processFaceDetect(frame, client); if (res != OK) break; - // Must be last - listener can take ownership of frame - res = processListener(frame, client); + res = processListeners(frame, client); if (res != OK) break; if (!frame.isEmpty()) { @@ -114,11 +126,11 @@ void FrameProcessor::processNewFrames(sp<Camera2Client> &client) { return; } -status_t FrameProcessor::processListener(CameraMetadata &frame, +status_t FrameProcessor::processListeners(const CameraMetadata &frame, sp<Camera2Client> &client) { status_t res; ATRACE_CALL(); - camera_metadata_entry_t entry; + camera_metadata_ro_entry_t entry; entry = frame.find(ANDROID_REQUEST_ID); if (entry.count == 0) { @@ -127,22 +139,30 @@ status_t FrameProcessor::processListener(CameraMetadata &frame, return BAD_VALUE; } int32_t frameId = entry.data.i32[0]; - ALOGV("%s: Got frame with ID %d", __FUNCTION__, frameId); - sp<FilteredListener> listener; + List<sp<FilteredListener> > listeners; { Mutex::Autolock l(mInputMutex); - ssize_t listenerIndex = mListeners.indexOfKey(frameId); - if (listenerIndex != NAME_NOT_FOUND) { - listener = mListeners[listenerIndex].promote(); - if (listener == 0) { - mListeners.removeItemsAt(listenerIndex, 1); + + List<RangeListener>::iterator item = mRangeListeners.begin(); + while (item != mRangeListeners.end()) { + if (frameId >= item->minId && + frameId < item->maxId) { + sp<FilteredListener> listener = item->listener.promote(); + if (listener == 0) { + item = mRangeListeners.erase(item); + continue; + } else { + listeners.push_back(listener); + } } + item++; } } - - if (listener != 0) { - listener->onFrameAvailable(frameId, frame); + ALOGV("Got %d range listeners out of %d", listeners.size(), mRangeListeners.size()); + List<sp<FilteredListener> >::iterator item = listeners.begin(); + for (; item != listeners.end(); item++) { + (*item)->onFrameAvailable(frameId, frame); } return OK; } diff --git a/services/camera/libcameraservice/camera2/FrameProcessor.h b/services/camera/libcameraservice/camera2/FrameProcessor.h index cc8c128..3bd4e25 100644 --- a/services/camera/libcameraservice/camera2/FrameProcessor.h +++ b/services/camera/libcameraservice/camera2/FrameProcessor.h @@ -21,6 +21,7 @@ #include <utils/String16.h> #include <utils/Vector.h> #include <utils/KeyedVector.h> +#include <utils/List.h> #include "CameraMetadata.h" struct camera_frame_metadata; @@ -40,15 +41,14 @@ class FrameProcessor: public Thread { ~FrameProcessor(); struct FilteredListener: virtual public RefBase { - // Listener may take ownership of frame - virtual void onFrameAvailable(int32_t frameId, CameraMetadata &frame) = 0; + virtual void onFrameAvailable(int32_t frameId, + const CameraMetadata &frame) = 0; }; - // Register a listener for a specific frame ID (android.request.id). - // De-registers any existing listeners for that ID - status_t registerListener(int32_t id, wp<FilteredListener> listener); - - status_t removeListener(int32_t id); + // Register a listener for a range of IDs [minId, maxId). Multiple listeners + // can be listening to the same range + status_t registerListener(int32_t minId, int32_t maxId, wp<FilteredListener> listener); + status_t removeListener(int32_t minId, int32_t maxId, wp<FilteredListener> listener); void dump(int fd, const Vector<String16>& args); private: @@ -58,14 +58,20 @@ class FrameProcessor: public Thread { virtual bool threadLoop(); Mutex mInputMutex; - KeyedVector<int32_t, wp<FilteredListener> > mListeners; + + struct RangeListener { + int32_t minId; + int32_t maxId; + wp<FilteredListener> listener; + }; + List<RangeListener> mRangeListeners; void processNewFrames(sp<Camera2Client> &client); status_t processFaceDetect(const CameraMetadata &frame, sp<Camera2Client> &client); - status_t processListener(CameraMetadata &frame, + status_t processListeners(const CameraMetadata &frame, sp<Camera2Client> &client); CameraMetadata mLastFrame; diff --git a/services/camera/libcameraservice/camera2/StreamingProcessor.cpp b/services/camera/libcameraservice/camera2/StreamingProcessor.cpp index 8921172..207f780 100644 --- a/services/camera/libcameraservice/camera2/StreamingProcessor.cpp +++ b/services/camera/libcameraservice/camera2/StreamingProcessor.cpp @@ -33,7 +33,10 @@ namespace camera2 { StreamingProcessor::StreamingProcessor(wp<Camera2Client> client): mClient(client), + mActiveRequest(NONE), + mPreviewRequestId(Camera2Client::kPreviewRequestIdStart), mPreviewStreamId(NO_STREAM), + mRecordingRequestId(Camera2Client::kRecordingRequestIdStart), mRecordingStreamId(NO_STREAM), mRecordingHeapCount(kDefaultRecordingHeapCount) { @@ -90,7 +93,12 @@ status_t StreamingProcessor::updatePreviewRequest(const Parameters ¶ms) { } res = mPreviewRequest.update(ANDROID_REQUEST_ID, - &Camera2Client::kPreviewRequestId, 1); + &mPreviewRequestId, 1); + if (res != OK) { + ALOGE("%s: Camera %d: Unable to update request id for preview: %s (%d)", + __FUNCTION__, client->getCameraId(), strerror(-res), res); + return res; + } return OK; } @@ -190,7 +198,7 @@ status_t StreamingProcessor::deletePreviewStream() { return OK; } -status_t StreamingProcessor::getPreviewStreamId() const { +int StreamingProcessor::getPreviewStreamId() const { Mutex::Autolock m(mMutex); return mPreviewStreamId; } @@ -246,6 +254,14 @@ status_t StreamingProcessor::updateRecordingRequest(const Parameters ¶ms) { return res; } + res = mRecordingRequest.update(ANDROID_REQUEST_ID, + &mRecordingRequestId, 1); + if (res != OK) { + ALOGE("%s: Camera %d: Unable to update request id for request: %s (%d)", + __FUNCTION__, client->getCameraId(), strerror(-res), res); + return res; + } + return OK; } @@ -342,7 +358,7 @@ status_t StreamingProcessor::deleteRecordingStream() { return OK; } -status_t StreamingProcessor::getRecordingStreamId() const { +int StreamingProcessor::getRecordingStreamId() const { return mRecordingStreamId; } @@ -351,6 +367,8 @@ status_t StreamingProcessor::startStream(StreamType type, ATRACE_CALL(); status_t res; + if (type == NONE) return INVALID_OPERATION; + sp<Camera2Client> client = mClient.promote(); if (client == 0) return INVALID_OPERATION; @@ -384,6 +402,7 @@ status_t StreamingProcessor::startStream(StreamType type, __FUNCTION__, client->getCameraId(), strerror(-res), res); return res; } + mActiveRequest = type; return OK; } @@ -392,6 +411,8 @@ status_t StreamingProcessor::stopStream() { ATRACE_CALL(); status_t res; + Mutex::Autolock m(mMutex); + sp<Camera2Client> client = mClient.promote(); if (client == 0) return INVALID_OPERATION; sp<Camera2Device> device = client->getCameraDevice(); @@ -402,11 +423,38 @@ status_t StreamingProcessor::stopStream() { __FUNCTION__, client->getCameraId(), strerror(-res), res); return res; } - res = device->waitUntilDrained(); - if (res != OK) { - ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)", - __FUNCTION__, client->getCameraId(), strerror(-res), res); - return res; + mActiveRequest = NONE; + + return OK; +} + +int32_t StreamingProcessor::getActiveRequestId() const { + Mutex::Autolock m(mMutex); + switch (mActiveRequest) { + case NONE: + return 0; + case PREVIEW: + return mPreviewRequestId; + case RECORD: + return mRecordingRequestId; + default: + ALOGE("%s: Unexpected mode %d", __FUNCTION__, mActiveRequest); + return 0; + } +} + +status_t StreamingProcessor::incrementStreamingIds() { + ATRACE_CALL(); + Mutex::Autolock m(mMutex); + + status_t res; + mPreviewRequestId++; + if (mPreviewRequestId >= Camera2Client::kPreviewRequestIdEnd) { + mPreviewRequestId = Camera2Client::kPreviewRequestIdStart; + } + mRecordingRequestId++; + if (mRecordingRequestId >= Camera2Client::kRecordingRequestIdEnd) { + mRecordingRequestId = Camera2Client::kRecordingRequestIdStart; } return OK; } diff --git a/services/camera/libcameraservice/camera2/StreamingProcessor.h b/services/camera/libcameraservice/camera2/StreamingProcessor.h index ac58614..96b100f 100644 --- a/services/camera/libcameraservice/camera2/StreamingProcessor.h +++ b/services/camera/libcameraservice/camera2/StreamingProcessor.h @@ -57,6 +57,7 @@ class StreamingProcessor: public BufferItemConsumer::FrameAvailableListener { int getRecordingStreamId() const; enum StreamType { + NONE, PREVIEW, RECORD }; @@ -65,6 +66,11 @@ class StreamingProcessor: public BufferItemConsumer::FrameAvailableListener { status_t stopStream(); + // Returns the request ID for the currently streaming request + // Returns 0 if there is no active request. + status_t getActiveRequestId() const; + status_t incrementStreamingIds(); + // Callback for new recording frames from HAL virtual void onFrameAvailable(); // Callback from stagefright which returns used recording frames @@ -81,12 +87,16 @@ class StreamingProcessor: public BufferItemConsumer::FrameAvailableListener { wp<Camera2Client> mClient; + StreamType mActiveRequest; + // Preview-related members + int32_t mPreviewRequestId; int mPreviewStreamId; CameraMetadata mPreviewRequest; sp<ANativeWindow> mPreviewWindow; // Recording-related members + int32_t mRecordingRequestId; int mRecordingStreamId; int mRecordingFrameCount; sp<BufferItemConsumer> mRecordingConsumer; diff --git a/services/camera/libcameraservice/camera2/ZslProcessor.cpp b/services/camera/libcameraservice/camera2/ZslProcessor.cpp index 56e9743..5208574 100644 --- a/services/camera/libcameraservice/camera2/ZslProcessor.cpp +++ b/services/camera/libcameraservice/camera2/ZslProcessor.cpp @@ -69,16 +69,16 @@ void ZslProcessor::onFrameAvailable() { } } -void ZslProcessor::onFrameAvailable(int32_t frameId, CameraMetadata &frame) { +void ZslProcessor::onFrameAvailable(int32_t frameId, const CameraMetadata &frame) { Mutex::Autolock l(mInputMutex); - camera_metadata_entry_t entry; + camera_metadata_ro_entry_t entry; entry = frame.find(ANDROID_SENSOR_TIMESTAMP); nsecs_t timestamp = entry.data.i64[0]; ALOGVV("Got preview frame for timestamp %lld", timestamp); if (mState != RUNNING) return; - mFrameList.editItemAt(mFrameListHead).acquire(frame); + mFrameList.editItemAt(mFrameListHead) = frame; mFrameListHead = (mFrameListHead + 1) % kFrameListDepth; findMatchesLocked(); @@ -185,7 +185,9 @@ status_t ZslProcessor::updateStream(const Parameters ¶ms) { return res; } } - client->registerFrameListener(Camera2Client::kPreviewRequestId, this); + client->registerFrameListener(Camera2Client::kPreviewRequestIdStart, + Camera2Client::kPreviewRequestIdEnd, + this); return OK; } @@ -297,7 +299,7 @@ status_t ZslProcessor::pushToReprocess(int32_t requestId) { return INVALID_OPERATION; } - res = client->getCameraDevice()->clearStreamingRequest(); + res = client->stopStream(); if (res != OK) { ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: " "%s (%d)", diff --git a/services/camera/libcameraservice/camera2/ZslProcessor.h b/services/camera/libcameraservice/camera2/ZslProcessor.h index 1f433ce..c80e7f4 100644 --- a/services/camera/libcameraservice/camera2/ZslProcessor.h +++ b/services/camera/libcameraservice/camera2/ZslProcessor.h @@ -52,7 +52,7 @@ class ZslProcessor: // From mZslConsumer virtual void onFrameAvailable(); // From FrameProcessor - virtual void onFrameAvailable(int32_t frameId, CameraMetadata &frame); + virtual void onFrameAvailable(int32_t frameId, const CameraMetadata &frame); virtual void onBufferReleased(buffer_handle_t *handle); |