Camera: implement signalPipelineDrain API

SignalPipelineDrain will be sent after the request
thread has stopped sending capture requests so
HAL can expect no more capture requests are sent
after they receive this call.

Test: CTS
Bug: 109829698
Change-Id: I6f75c28ff0998a8edc80f9af9ebe727c585ea6e9
gugelfrei
Yin-Chia Yeh 6 years ago
parent 4ee3543809
commit 7447f0fc15

@ -1619,6 +1619,15 @@ void Camera3Device::StreamSet::clear() {
return mData.clear();
}
std::vector<int> Camera3Device::StreamSet::getStreamIds() {
std::lock_guard<std::mutex> lock(mLock);
std::vector<int> streamIds(mData.size());
for (size_t i = 0; i < mData.size(); i++) {
streamIds[i] = mData.keyAt(i);
}
return streamIds;
}
status_t Camera3Device::createStream(sp<Surface> consumer,
uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
@ -2130,6 +2139,12 @@ status_t Camera3Device::waitUntilStateThenRelock(bool active, nsecs_t timeout) {
break;
}
// Notify HAL to start draining
if (!active && mUseHalBufManager) {
auto streamIds = mOutputStreams.getStreamIds();
mRequestThread->signalPipelineDrain(streamIds);
}
res = mStatusChanged.waitRelative(mLock, timeout);
if (res != OK) break;
@ -3902,26 +3917,49 @@ status_t Camera3Device::HalInterface::configureStreams(const camera_metadata_t *
// Invoke configureStreams
device::V3_3::HalStreamConfiguration finalConfiguration;
device::V3_4::HalStreamConfiguration finalConfiguration3_4;
common::V1_0::Status status;
// See if we have v3.4 or v3.3 HAL
if (mHidlSession_3_4 != nullptr) {
// We do; use v3.4 for the call
ALOGV("%s: v3.4 device found", __FUNCTION__);
device::V3_4::HalStreamConfiguration finalConfiguration3_4;
auto err = mHidlSession_3_4->configureStreams_3_4(requestedConfiguration3_4,
[&status, &finalConfiguration3_4]
auto configStream34Cb = [&status, &finalConfiguration3_4]
(common::V1_0::Status s, const device::V3_4::HalStreamConfiguration& halConfiguration) {
finalConfiguration3_4 = halConfiguration;
status = s;
});
if (!err.isOk()) {
ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
return DEAD_OBJECT;
};
auto postprocConfigStream34 = [&finalConfiguration, &finalConfiguration3_4]
(hardware::Return<void>& err) -> status_t {
if (!err.isOk()) {
ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
return DEAD_OBJECT;
}
finalConfiguration.streams.resize(finalConfiguration3_4.streams.size());
for (size_t i = 0; i < finalConfiguration3_4.streams.size(); i++) {
finalConfiguration.streams[i] = finalConfiguration3_4.streams[i].v3_3;
}
return OK;
};
// See if we have v3.4 or v3.3 HAL
if (mHidlSession_3_5 != nullptr) {
ALOGV("%s: v3.5 device found", __FUNCTION__);
device::V3_5::StreamConfiguration requestedConfiguration3_5;
requestedConfiguration3_5.v3_4 = requestedConfiguration3_4;
requestedConfiguration3_5.streamConfigCounter = mNextStreamConfigCounter++;
auto err = mHidlSession_3_5->configureStreams_3_5(
requestedConfiguration3_5, configStream34Cb);
res = postprocConfigStream34(err);
if (res != OK) {
return res;
}
finalConfiguration.streams.resize(finalConfiguration3_4.streams.size());
for (size_t i = 0; i < finalConfiguration3_4.streams.size(); i++) {
finalConfiguration.streams[i] = finalConfiguration3_4.streams[i].v3_3;
} else if (mHidlSession_3_4 != nullptr) {
// We do; use v3.4 for the call
ALOGV("%s: v3.4 device found", __FUNCTION__);
device::V3_4::HalStreamConfiguration finalConfiguration3_4;
auto err = mHidlSession_3_4->configureStreams_3_4(
requestedConfiguration3_4, configStream34Cb);
res = postprocConfigStream34(err);
if (res != OK) {
return res;
}
} else if (mHidlSession_3_3 != nullptr) {
// We do; use v3.3 for the call
@ -4292,6 +4330,20 @@ status_t Camera3Device::HalInterface::close() {
return res;
}
void Camera3Device::HalInterface::signalPipelineDrain(const std::vector<int>& streamIds) {
ATRACE_NAME("CameraHal::signalPipelineDrain");
if (!valid() || mHidlSession_3_5 == nullptr) {
ALOGE("%s called on invalid camera!", __FUNCTION__);
return;
}
auto err = mHidlSession_3_5->signalStreamFlush(streamIds, mNextStreamConfigCounter);
if (!err.isOk()) {
ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
return;
}
}
void Camera3Device::HalInterface::getInflightBufferKeys(
std::vector<std::pair<int32_t, int32_t>>* out) {
std::lock_guard<std::mutex> lock(mInflightLock);
@ -4418,6 +4470,7 @@ Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
mReconfigured(false),
mDoPause(false),
mPaused(true),
mNotifyPipelineDrain(false),
mFrameNumber(0),
mLatestRequestId(NAME_NOT_FOUND),
mCurrentAfTriggerId(0),
@ -5369,6 +5422,21 @@ bool Camera3Device::RequestThread::isOutputSurfacePending(int streamId, size_t s
return false;
}
void Camera3Device::RequestThread::signalPipelineDrain(const std::vector<int>& streamIds) {
if (!mUseHalBufManager) {
ALOGE("%s called for camera device not supporting HAL buffer management", __FUNCTION__);
return;
}
Mutex::Autolock pl(mPauseLock);
if (mPaused) {
return mInterface->signalPipelineDrain(streamIds);
}
// If request thread is still busy, wait until paused then notify HAL
mNotifyPipelineDrain = true;
mStreamIdsToBeDrained = streamIds;
}
nsecs_t Camera3Device::getExpectedInFlightDuration() {
ATRACE_CALL();
Mutex::Autolock al(mInFlightLock);
@ -5546,6 +5614,11 @@ sp<Camera3Device::CaptureRequest>
if (statusTracker != 0) {
statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
}
if (mNotifyPipelineDrain) {
mInterface->signalPipelineDrain(mStreamIdsToBeDrained);
mNotifyPipelineDrain = false;
mStreamIdsToBeDrained.clear();
}
}
// Stop waiting for now and let thread management happen
return NULL;
@ -5630,6 +5703,11 @@ bool Camera3Device::RequestThread::waitIfPaused() {
if (statusTracker != 0) {
statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
}
if (mNotifyPipelineDrain) {
mInterface->signalPipelineDrain(mStreamIdsToBeDrained);
mNotifyPipelineDrain = false;
mStreamIdsToBeDrained.clear();
}
}
res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);

@ -285,6 +285,8 @@ class Camera3Device :
status_t dump(int fd);
status_t close();
void signalPipelineDrain(const std::vector<int>& streamIds);
// method to extract buffer's unique ID
// return pair of (newlySeenBuffer?, bufferId)
std::pair<bool, uint64_t> getBufferId(const buffer_handle_t& buf, int streamId);
@ -372,6 +374,8 @@ class Camera3Device :
// Buffers given to HAL through requestStreamBuffer API
std::mutex mRequestedBuffersLock;
std::unordered_map<uint64_t, buffer_handle_t*> mRequestedBuffers;
uint32_t mNextStreamConfigCounter = 1;
};
sp<HalInterface> mInterface;
@ -415,6 +419,7 @@ class Camera3Device :
// get by (underlying) vector index
sp<camera3::Camera3OutputStreamInterface> operator[] (size_t index);
size_t size() const;
std::vector<int> getStreamIds();
void clear();
private:
@ -808,6 +813,8 @@ class Camera3Device :
mRequestLatency.dump(fd, name);
}
void signalPipelineDrain(const std::vector<int>& streamIds);
protected:
virtual bool threadLoop();
@ -917,12 +924,13 @@ class Camera3Device :
bool mReconfigured;
// Used by waitIfPaused, waitForNextRequest, and waitUntilPaused
// Used by waitIfPaused, waitForNextRequest, waitUntilPaused, and signalPipelineDrain
Mutex mPauseLock;
bool mDoPause;
Condition mDoPauseSignal;
bool mPaused;
Condition mPausedSignal;
bool mNotifyPipelineDrain;
std::vector<int> mStreamIdsToBeDrained;
sp<CaptureRequest> mPrevRequest;
int32_t mPrevTriggers;

Loading…
Cancel
Save