Camera: Drain attached and queued input buffers during reconfiguration

Application may first call ImageWriter.queueInputImage without sending any capture
request before reconfiguring capture session using the same ImageWriter.
In this case, the stale buffers still exist in the buffer qeueue, and
ImageWriter.queueInputImage may stuck at waiting for free slots in the
new capture session.

Clear up all such queued buffers in the input buffer queue during stream
reconfiguration.

Test: Run testMandatoryReprocessConfigurations 300 times
Test: testQueueImageWithoutRequest
Bug: 138729150
Change-Id: Ie102dd018983bbd972f7c647d8c86c976a44e754
gugelfrei
Shuzhen Wang 5 years ago
parent 0f6aaed13c
commit 0cf01cbcbc

@ -2802,6 +2802,27 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,
mOperatingMode = operatingMode;
}
// In case called from configureStreams, abort queued input buffers not belonging to
// any pending requests.
if (mInputStream != NULL && notifyRequestThread) {
while (true) {
camera3_stream_buffer_t inputBuffer;
status_t res = mInputStream->getInputBuffer(&inputBuffer,
/*respectHalLimit*/ false);
if (res != OK) {
// Exhausted acquiring all input buffers.
break;
}
inputBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
res = mInputStream->returnInputBuffer(inputBuffer);
if (res != OK) {
ALOGE("%s: %d: couldn't return input buffer while clearing input queue: "
"%s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
}
}
}
if (!mNeedConfig) {
ALOGV("%s: Skipping config, no stream changes", __FUNCTION__);
return OK;
@ -5084,6 +5105,7 @@ status_t Camera3Device::RequestThread::clear(
ALOGW("%s: %d: couldn't get input buffer while clearing the request "
"list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
} else {
inputBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
res = (*it)->mInputStream->returnInputBuffer(inputBuffer);
if (res != OK) {
ALOGE("%s: %d: couldn't return input buffer while clearing the request "

@ -71,7 +71,8 @@ status_t Camera3InputStream::getInputBufferLocked(
res = mConsumer->acquireBuffer(&bufferItem, /*waitForFence*/false);
if (res != OK) {
ALOGE("%s: Stream %d: Can't acquire next output buffer: %s (%d)",
// This may or may not be an error condition depending on caller.
ALOGV("%s: Stream %d: Can't acquire next output buffer: %s (%d)",
__FUNCTION__, mId, strerror(-res), res);
return res;
}

Loading…
Cancel
Save