guration
该函数主要执行configureQueueLocked和registerBuffersLocked两个函数
status_t Camera3OutputStream::configureQueueLocked() {
status_t res;
mTraceFirstBuffer = true;
if ((res = Camera3IOStreamBase::configureQueueLocked()) != OK) {
return res;
}
ALOG_ASSERT(mConsumer != 0, mConsumer should never be NULL);
// Configure consumer-side ANativeWindow interface
res = native_window_api_connect(mConsumer.get(),
NATIVE_WINDOW_API_CAMERA);
if (res != OK) {
ALOGE(%s: Unable to connect to native window for stream %d,
__FUNCTION__, mId);
return res;
}
res = native_window_set_usage(mConsumer.get(), camera3_stream::usage);
if (res != OK) {
ALOGE(%s: Unable to configure usage %08x for stream %d,
__FUNCTION__, camera3_stream::usage, mId);
return res;
}
res = native_window_set_scaling_mode(mConsumer.get(),
NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
if (res != OK) {
ALOGE(%s: Unable to configure stream scaling: %s (%d),
__FUNCTION__, strerror(-res), res);
return res;
}
if (mMaxSize == 0) {
// For buffers of known size
res = native_window_set_buffers_dimensions(mConsumer.get(),
camera3_stream::width, camera3_stream::height);
} else {
// For buffers with bounded size
res = native_window_set_buffers_dimensions(mConsumer.get(),
mMaxSize, 1);
}
if (res != OK) {
ALOGE(%s: Unable to configure stream buffer dimensions
%d x %d (maxSize %zu) for stream %d,
__FUNCTION__, camera3_stream::width, camera3_stream::height,
mMaxSize, mId);
return res;
}
res = native_window_set_buffers_format(mConsumer.get(),
camera3_stream::format);
if (res != OK) {
ALOGE(%s: Unable to configure stream buffer format %#x for stream %d,
__FUNCTION__, camera3_stream::format, mId);
return res;
}
int maxConsumerBuffers;
res = mConsumer->query(mConsumer.get(),
NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);//支持的最大buffer数量
if (res != OK) {
ALOGE(%s: Unable to query consumer undequeued
buffer count for stream %d, __FUNCTION__, mId);
return res;
}
ALOGV(%s: Consumer wants %d buffers, HAL wants %d, __FUNCTION__,
maxConsumerBuffers, camera3_stream::max_buffers);
if (camera3_stream::max_buffers == 0) {
ALOGE(%s: Camera HAL requested max_buffer count: %d, requires at least 1,
__FUNCTION__, camera3_stream::max_buffers);
return INVALID_OPERATION;
}
mTotalBufferCount = maxConsumerBuffers + camera3_stream::max_buffers;//至少2个buffer
mHandoutTotalBufferCount = 0;
mFrameCount = 0;
mLastTimestamp = 0;
res = native_window_set_buffer_count(mConsumer.get(),
mTotalBufferCount);
if (res != OK) {
ALOGE(%s: Unable to set buffer count for stream %d,
__FUNCTION__, mId);
return res;
}
res = native_window_set_buffers_transform(mConsumer.get(),
mTransform);
if (res != OK) {
ALOGE(%s: Unable to configure stream transform to %x: %s (%d),
__FUNCTION__, mTransform, strerror(-res), res);
}
return OK;
}
如果你对SurfaceFlinger的架构熟悉的话,该代码会相对比较好理解。本质是根据当前stream设置的buffer属性,将这些属性值通过ANativeWindow这个接口传递给Consumer侧去维护:
这里重点关注以下几个buffer的相关属性信息:
比如native_window_set_buffer_count是设置当前Window所需要的buffer数目:
总的当前stream下的buffer个数总数为mTotalBufferCount = maxConsumerBuffers + camera3_stream::max_buffers。其中camera3_stream::max_buffer需要的buffer总数由configureStreams时HAL3底层的Device来决