From 6b7a2294b9e4da784cfe4b562ee1720ad606c852 Mon Sep 17 00:00:00 2001 From: Yin-Chia Yeh Date: Tue, 9 Sep 2014 13:31:46 -0700 Subject: camera2: skip capture result after clearZslQueue After ZSL queue is cleared, don't add capture result to ZSL queue if its corresponding buffer has been cleared. Bug: 17185356 Change-Id: Iddac39ab09b2560e2ce9390895927217c1736d5a --- .../libcameraservice/api1/client2/ZslProcessor3.cpp | 7 +++++-- .../libcameraservice/api1/client2/ZslProcessor3.h | 1 + .../libcameraservice/device3/Camera3ZslStream.cpp | 12 ++++++++---- .../camera/libcameraservice/device3/Camera3ZslStream.h | 6 ++++-- .../camera/libcameraservice/gui/RingBufferConsumer.cpp | 18 +++++++++++++++++- .../camera/libcameraservice/gui/RingBufferConsumer.h | 6 ++++++ 6 files changed, 41 insertions(+), 9 deletions(-) diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp index 2d31275..227b169 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp +++ b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp @@ -44,6 +44,7 @@ ZslProcessor3::ZslProcessor3( sp client, wp sequencer): Thread(false), + mLatestClearedBufferTimestamp(0), mState(RUNNING), mClient(client), mSequencer(sequencer), @@ -107,7 +108,6 @@ void ZslProcessor3::onResultAvailable(const CaptureResult &result) { ALOGE("%s: metadata doesn't have timestamp, skip this result", __FUNCTION__); return; } - (void)timestamp; entry = result.mMetadata.find(ANDROID_REQUEST_FRAME_COUNT); if (entry.count == 0) { @@ -120,6 +120,9 @@ void ZslProcessor3::onResultAvailable(const CaptureResult &result) { if (mState != RUNNING) return; + // Corresponding buffer has been cleared. No need to push into mFrameList + if (timestamp <= mLatestClearedBufferTimestamp) return; + mFrameList.editItemAt(mFrameListHead) = result.mMetadata; mFrameListHead = (mFrameListHead + 1) % mFrameListDepth; } @@ -392,7 +395,7 @@ status_t ZslProcessor3::clearZslQueueLocked() { if (mZslStream != 0) { // clear result metadata list first. clearZslResultQueueLocked(); - return mZslStream->clearInputRingBuffer(); + return mZslStream->clearInputRingBuffer(&mLatestClearedBufferTimestamp); } return OK; } diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor3.h b/services/camera/libcameraservice/api1/client2/ZslProcessor3.h index daa352b..8894364 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessor3.h +++ b/services/camera/libcameraservice/api1/client2/ZslProcessor3.h @@ -82,6 +82,7 @@ class ZslProcessor3 : private: static const nsecs_t kWaitDuration = 10000000; // 10 ms + nsecs_t mLatestClearedBufferTimestamp; enum { RUNNING, diff --git a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp index 92bf81b..81330ea 100644 --- a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp +++ b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp @@ -315,20 +315,24 @@ status_t Camera3ZslStream::enqueueInputBufferByTimestamp( return OK; } -status_t Camera3ZslStream::clearInputRingBuffer() { +status_t Camera3ZslStream::clearInputRingBuffer(nsecs_t* latestTimestamp) { Mutex::Autolock l(mLock); - return clearInputRingBufferLocked(); + return clearInputRingBufferLocked(latestTimestamp); } -status_t Camera3ZslStream::clearInputRingBufferLocked() { +status_t Camera3ZslStream::clearInputRingBufferLocked(nsecs_t* latestTimestamp) { + + if (latestTimestamp) { + *latestTimestamp = mProducer->getLatestTimestamp(); + } mInputBufferQueue.clear(); return mProducer->clear(); } status_t Camera3ZslStream::disconnectLocked() { - clearInputRingBufferLocked(); + clearInputRingBufferLocked(NULL); return Camera3OutputStream::disconnectLocked(); } diff --git a/services/camera/libcameraservice/device3/Camera3ZslStream.h b/services/camera/libcameraservice/device3/Camera3ZslStream.h index d89c38d..5323a49 100644 --- a/services/camera/libcameraservice/device3/Camera3ZslStream.h +++ b/services/camera/libcameraservice/device3/Camera3ZslStream.h @@ -59,8 +59,10 @@ class Camera3ZslStream : /** * Clears the buffers that can be used by enqueueInputBufferByTimestamp + * latestTimestamp will be filled with the largest timestamp of buffers + * being cleared, 0 if there is no buffer being clear. */ - status_t clearInputRingBuffer(); + status_t clearInputRingBuffer(nsecs_t* latestTimestamp); protected: @@ -100,7 +102,7 @@ class Camera3ZslStream : // Disconnet the Camera3ZslStream specific bufferQueues. virtual status_t disconnectLocked(); - status_t clearInputRingBufferLocked(); + status_t clearInputRingBufferLocked(nsecs_t* latestTimestamp); }; // class Camera3ZslStream diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp index e4ec5fd..f8562ec 100644 --- a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp +++ b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp @@ -41,7 +41,8 @@ RingBufferConsumer::RingBufferConsumer(const sp& consume uint32_t consumerUsage, int bufferCount) : ConsumerBase(consumer), - mBufferCount(bufferCount) + mBufferCount(bufferCount), + mLatestTimestamp(0) { mConsumer->setConsumerUsageBits(consumerUsage); mConsumer->setMaxAcquiredBufferCount(bufferCount); @@ -152,6 +153,14 @@ status_t RingBufferConsumer::clear() { return OK; } +nsecs_t RingBufferConsumer::getLatestTimestamp() { + Mutex::Autolock _l(mMutex); + if (mBufferItemList.size() == 0) { + return 0; + } + return mLatestTimestamp; +} + void RingBufferConsumer::pinBufferLocked(const BufferItem& item) { List::iterator it, end; @@ -302,6 +311,13 @@ void RingBufferConsumer::onFrameAvailable() { item.mTimestamp, mBufferItemList.size(), mBufferCount); + if (item.mTimestamp < mLatestTimestamp) { + BI_LOGE("Timestamp decreases from %" PRId64 " to %" PRId64, + mLatestTimestamp, item.mTimestamp); + } + + mLatestTimestamp = item.mTimestamp; + item.mGraphicBuffer = mSlots[item.mBuf].mGraphicBuffer; } // end of mMutex lock diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.h b/services/camera/libcameraservice/gui/RingBufferConsumer.h index a03736d..da97a11 100644 --- a/services/camera/libcameraservice/gui/RingBufferConsumer.h +++ b/services/camera/libcameraservice/gui/RingBufferConsumer.h @@ -159,6 +159,9 @@ class RingBufferConsumer : public ConsumerBase, // Release all the non-pinned buffers in the ring buffer status_t clear(); + // Return 0 if RingBuffer is empty, otherwise return timestamp of latest buffer. + nsecs_t getLatestTimestamp(); + private: // Override ConsumerBase::onFrameAvailable @@ -180,6 +183,9 @@ class RingBufferConsumer : public ConsumerBase, // List of acquired buffers in our ring buffer List mBufferItemList; const int mBufferCount; + + // Timestamp of latest buffer + nsecs_t mLatestTimestamp; }; } // namespace android -- cgit v1.1