Merge "Camera: Fix high speed recording failure due to prepare()" am: 0de0bf9db7 am: 6808238a51

am: 6ff79a0dd1

Change-Id: I2d6d71f6e145441b69c016dc7bf8f5403453ddce
gugelfrei
Shuzhen Wang 6 years ago committed by android-build-merger
commit 45146a2c3b

@ -2272,8 +2272,8 @@ sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
return NULL; return NULL;
} }
} }
// Check if stream is being prepared // Check if stream prepare is blocking requests.
if (mInputStream->isPreparing()) { if (mInputStream->isBlockedByPrepare()) {
CLOGE("Request references an input stream that's being prepared!"); CLOGE("Request references an input stream that's being prepared!");
return NULL; return NULL;
} }
@ -2323,8 +2323,8 @@ sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
return NULL; return NULL;
} }
} }
// Check if stream is being prepared // Check if stream prepare is blocking requests.
if (stream->isPreparing()) { if (stream->isBlockedByPrepare()) {
CLOGE("Request references an output stream that's being prepared!"); CLOGE("Request references an output stream that's being prepared!");
return NULL; return NULL;
} }
@ -4908,7 +4908,8 @@ status_t Camera3Device::RequestThread::prepareHalRequests() {
// Only try to prepare video stream on the first video request. // Only try to prepare video stream on the first video request.
mPrepareVideoStream = false; mPrepareVideoStream = false;
res = outputStream->startPrepare(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX); res = outputStream->startPrepare(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX,
false /*blockRequest*/);
while (res == NOT_ENOUGH_DATA) { while (res == NOT_ENOUGH_DATA) {
res = outputStream->prepareNextBuffer(); res = outputStream->prepareNextBuffer();
} }
@ -5588,7 +5589,7 @@ status_t Camera3Device::PreparerThread::prepare(int maxCount, sp<Camera3StreamIn
Mutex::Autolock l(mLock); Mutex::Autolock l(mLock);
sp<NotificationListener> listener = mListener.promote(); sp<NotificationListener> listener = mListener.promote();
res = stream->startPrepare(maxCount); res = stream->startPrepare(maxCount, true /*blockRequest*/);
if (res == OK) { if (res == OK) {
// No preparation needed, fire listener right off // No preparation needed, fire listener right off
ALOGV("%s: Stream %d already prepared", __FUNCTION__, stream->getId()); ALOGV("%s: Stream %d already prepared", __FUNCTION__, stream->getId());
@ -5676,7 +5677,7 @@ status_t Camera3Device::PreparerThread::resume() {
auto it = mPendingStreams.begin(); auto it = mPendingStreams.begin();
for (; it != mPendingStreams.end();) { for (; it != mPendingStreams.end();) {
res = it->second->startPrepare(it->first); res = it->second->startPrepare(it->first, true /*blockRequest*/);
if (res == OK) { if (res == OK) {
if (listener != NULL) { if (listener != NULL) {
listener->notifyPrepared(it->second->getId()); listener->notifyPrepared(it->second->getId());

@ -61,6 +61,7 @@ Camera3Stream::Camera3Stream(int id,
mOldUsage(0), mOldUsage(0),
mOldMaxBuffers(0), mOldMaxBuffers(0),
mPrepared(false), mPrepared(false),
mPrepareBlockRequest(true),
mPreparedBufferIdx(0), mPreparedBufferIdx(0),
mLastMaxCount(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX), mLastMaxCount(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX),
mBufferLimitLatency(kBufferLimitLatencyBinSize), mBufferLimitLatency(kBufferLimitLatencyBinSize),
@ -328,6 +329,7 @@ status_t Camera3Stream::finishConfiguration() {
// Reset prepared state, since buffer config has changed, and existing // Reset prepared state, since buffer config has changed, and existing
// allocations are no longer valid // allocations are no longer valid
mPrepared = false; mPrepared = false;
mPrepareBlockRequest = true;
mStreamUnpreparable = false; mStreamUnpreparable = false;
status_t res; status_t res;
@ -389,7 +391,7 @@ bool Camera3Stream::isUnpreparable() {
return mStreamUnpreparable; return mStreamUnpreparable;
} }
status_t Camera3Stream::startPrepare(int maxCount) { status_t Camera3Stream::startPrepare(int maxCount, bool blockRequest) {
ATRACE_CALL(); ATRACE_CALL();
Mutex::Autolock l(mLock); Mutex::Autolock l(mLock);
@ -421,8 +423,6 @@ status_t Camera3Stream::startPrepare(int maxCount) {
return INVALID_OPERATION; return INVALID_OPERATION;
} }
size_t pipelineMax = getBufferCountLocked(); size_t pipelineMax = getBufferCountLocked();
size_t clampedCount = (pipelineMax < static_cast<size_t>(maxCount)) ? size_t clampedCount = (pipelineMax < static_cast<size_t>(maxCount)) ?
pipelineMax : static_cast<size_t>(maxCount); pipelineMax : static_cast<size_t>(maxCount);
@ -430,6 +430,7 @@ status_t Camera3Stream::startPrepare(int maxCount) {
pipelineMax : clampedCount; pipelineMax : clampedCount;
mPrepared = bufferCount <= mLastMaxCount; mPrepared = bufferCount <= mLastMaxCount;
mPrepareBlockRequest = blockRequest;
if (mPrepared) return OK; if (mPrepared) return OK;
@ -443,9 +444,9 @@ status_t Camera3Stream::startPrepare(int maxCount) {
return NOT_ENOUGH_DATA; return NOT_ENOUGH_DATA;
} }
bool Camera3Stream::isPreparing() const { bool Camera3Stream::isBlockedByPrepare() const {
Mutex::Autolock l(mLock); Mutex::Autolock l(mLock);
return mState == STATE_PREPARING; return mState == STATE_PREPARING && mPrepareBlockRequest;
} }
bool Camera3Stream::isAbandoned() const { bool Camera3Stream::isAbandoned() const {

@ -232,6 +232,11 @@ class Camera3Stream :
* *
* This call performs no allocation, so is quick to call. * This call performs no allocation, so is quick to call.
* *
* blockRequest specifies whether prepare will block upcoming capture
* request. This flag should only be set to false if the caller guarantees
* the whole buffer preparation process is done before capture request
* comes in.
*
* Returns: * Returns:
* OK if no more buffers need to be preallocated * OK if no more buffers need to be preallocated
* NOT_ENOUGH_DATA if calls to prepareNextBuffer are needed to finish * NOT_ENOUGH_DATA if calls to prepareNextBuffer are needed to finish
@ -240,12 +245,12 @@ class Camera3Stream :
* INVALID_OPERATION if called when not in CONFIGURED state, or a * INVALID_OPERATION if called when not in CONFIGURED state, or a
* valid buffer has already been returned to this stream. * valid buffer has already been returned to this stream.
*/ */
status_t startPrepare(int maxCount); status_t startPrepare(int maxCount, bool blockRequest);
/** /**
* Check if the stream is mid-preparing. * Check if the request on a stream is blocked by prepare.
*/ */
bool isPreparing() const; bool isBlockedByPrepare() const;
/** /**
* Continue stream buffer preparation by allocating the next * Continue stream buffer preparation by allocating the next
@ -535,6 +540,7 @@ class Camera3Stream :
// has been called sufficient number of times, or stream configuration // has been called sufficient number of times, or stream configuration
// had to register buffers with the HAL // had to register buffers with the HAL
bool mPrepared; bool mPrepared;
bool mPrepareBlockRequest;
Vector<camera3_stream_buffer_t> mPreparedBuffers; Vector<camera3_stream_buffer_t> mPreparedBuffers;
size_t mPreparedBufferIdx; size_t mPreparedBufferIdx;

@ -160,6 +160,11 @@ class Camera3StreamInterface : public virtual RefBase {
* PREPARING state. Otherwise, returns NOT_ENOUGH_DATA and transitions * PREPARING state. Otherwise, returns NOT_ENOUGH_DATA and transitions
* to PREPARING. * to PREPARING.
* *
* blockRequest specifies whether prepare will block upcoming capture
* request. This flag should only be set to false if the caller guarantees
* the whole buffer preparation process is done before capture request
* comes in.
*
* Returns: * Returns:
* OK if no more buffers need to be preallocated * OK if no more buffers need to be preallocated
* NOT_ENOUGH_DATA if calls to prepareNextBuffer are needed to finish * NOT_ENOUGH_DATA if calls to prepareNextBuffer are needed to finish
@ -168,12 +173,12 @@ class Camera3StreamInterface : public virtual RefBase {
* INVALID_OPERATION if called when not in CONFIGURED state, or a * INVALID_OPERATION if called when not in CONFIGURED state, or a
* valid buffer has already been returned to this stream. * valid buffer has already been returned to this stream.
*/ */
virtual status_t startPrepare(int maxCount) = 0; virtual status_t startPrepare(int maxCount, bool blockRequest) = 0;
/** /**
* Check if the stream is mid-preparing. * Check if the request on a stream is blocked by prepare.
*/ */
virtual bool isPreparing() const = 0; virtual bool isBlockedByPrepare() const = 0;
/** /**
* Continue stream buffer preparation by allocating the next * Continue stream buffer preparation by allocating the next

Loading…
Cancel
Save