CameraCaptureSession.StateCallback callback, Handler handler)
{
List<OutputConfiguration> outConfigurations = new ArrayList<>(outputs.size());
for (Surface surface : outputs) {
outConfigurations.add(new OutputConfiguration(surface));
}
createCaptureSessionInternal(null, outConfigurations, callback, handler,
/*operatingMode*/ICameraDeviceUser.NORMAL_MODE);
}
Surface.java java层的surface表示的什么?
frameworks/base/core/java/android/view/Surface.java
Handle onto a raw buffer that is being managed by the screen compositor.
A Surface is generally created by or from a consumer of image buffers.
frameworks/base/core/java/android/hardware/camera2/params/OutputConfiguration.java
public OutputConfiguration(@NonNull Surface surface) {
this(SURFACE_GROUP_ID_NONE, surface, ROTATION_0);
}
/*从输入的surface得到多个关于surface的属性*/
public OutputConfiguration(int surfaceGroupId, @NonNull Surface surface, int rotation) {
checkNotNull(surface, "Surface must not be null");
checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant");
mSurfaceGroupId = surfaceGroupId;
mSurfaceType = SURFACE_TYPE_UNKNOWN;
mSurfaces = new ArrayList<Surface>();
mSurfaces.add(surface);
mRotation = rotation;
mConfiguredSize = SurfaceUtils.getSurfaceSize(surface);
mConfiguredFormat = SurfaceUtils.getSurfaceFormat(surface);
mConfiguredDataspace = SurfaceUtils.getSurfaceDataspace(surface);
mConfiguredGenerationId = surface.getGenerationId();
mIsDeferredConfig = false;
mIsShared = false;
}
private void createCaptureSessionInternal(InputConfiguration inputConfig,
List<OutputConfiguration> outputConfigurations,
CameraCaptureSession.StateCallback callback, Handler handler,
int operatingMode) {
boolean configureSuccess = true;
try {
// configure streams and then block until IDLE
configureSuccess = configureStreamsChecked(inputConfig, outputConfigurations,
operatingMode);
}
// Fire onConfigured if configureOutputs succeeded, fire onConfigureFailed otherwise.
CameraCaptureSessionCore newSession = new CameraCaptureSessionImpl(mNextSessionId++, input,
callback, handler, this, mDeviceHandler,
configureSuccess);
}
下面只关注 configureStreamsChecked
/**
* Attempt to configure the input and outputs; the device goes to idle and then configures the
* new input and outputs if possible.
*/
public boolean configureStreamsChecked(InputConfiguration inputConfig,
List<OutputConfiguration> outputs, int operatingMode) {
waitUntilIdle();
mRemoteDevice.beginConfigure();
// Add all new streams
for (OutputConfiguration outConfig : outputs) {
if (addSet.contains(outConfig)) {
int streamId = mRemoteDevice.createStream(outConfig);
mConfiguredOutputs.put(streamId, outConfig);
}
}
operatingMode = (operatingMode | (customOpMode << 16));
mRemoteDevice.endConfigure(operatingMode)
}
createCaptureSession的过程出现了configureStream的概念,通过mRemoteDevice创建steam.
binder::Status CameraDeviceClient::createStream(
const hardware::camera2::params::OutputConfiguration &outputConfiguration,
/*out*/
int32_t* newStreamId) {
const std::vector<sp<IGraphicBufferProducer>>& bufferProducers = outputConfiguration.getGraphicBufferProducers();
size_t numBufferProducers = bufferProducers.size();
bool deferredConsumer = outputConfiguration.isDeferred();
bool isShared = outputConfiguration.isShared();
int surfaceType = outputConfiguration.getSurfaceType();
std::vector<sp<Surface>> surfaces;
std::vector<sp<IBinder>> binders;
OutputStreamInfo streamInfo;
bool isStreamInfoValid = false;
/*surface对应bufferProducers的个数决定stream的个数*/
for (auto& bufferProducer : bufferProducers) {
// Don't create multiple streams for the same target surface
sp<IBinder> binder = IInterface::asBinder(bufferProducer);
ssize_t index = mStreamMap.indexOfKey(binder);
sp<Surface> surface;
res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer);
binders.push_back(IInterface::asBinder(bufferProducer));
surfaces.push_back(surface);
}
mDevice->createStream(surfaces, deferredConsumer, streamInfo.width,
streamInfo.height, streamInfo.format, streamInfo.dataSpace,
static_cast<camera3_stream_rotation_t>(outputConfiguration.getRotation()),
&streamId, outputConfiguration.getSurfaceSetID(), isShared);
*newStreamId = streamId;
}
binder::Status CameraDeviceClient::createSurfaceFromGbp(
OutputStreamInfo& streamInfo, bool isStreamInfoValid,
sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp) {
/*在native层创建surface, 并赋值OutputStreamInfo*/
surface = new Surface(gbp, useAsync);
if (!isStreamInfoValid) {
streamInfo.width = width;
streamInfo.height = height;
streamInfo.format = format;
streamInfo.dataSpace = dataSpace;
streamInfo.consumerUsage = consumerUsage;
return binder::Status::ok();
}
}
status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
int streamSetId, bool isShared, uint64_t consumerUsage) {
sp<Camera3OutputStream> newStream;
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, format, dataSpace, rotation,
mTimestampOffset, streamSetId);
newStream->setBufferManager(mBufferManager);
res = mOutputStreams.add(mNextStreamId, newStream);
*id = mNextStreamId++;
}
Camera3OutputStream::Camera3OutputStream(int id,
sp<Surface> consumer,
uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera3_stream_rotation_t rotation,
nsecs_t timestampOffset, int setId) :
Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height,
/*maxSize*/0, format, dataSpace, rotation, setId),
mConsumer(consumer),
mTransform(0),
mTraceFirstBuffer(true),
mUseBufferManager(false),
mTimestampOffset(timestampOffset),
mConsumerUsage(0),
mDequeueBufferLatency(kDequeueLatencyBinSize) {
}
Camera3IOStreamBase::Camera3IOStreamBase(int id, camera3_stream_type_t type,
uint32_t width, uint32_t height, size_t maxSize, int format,
android_dataspace dataSpace, camera3_stream_rotation_t rotation, int setId) :
Camera3Stream(id, type,
width, height, maxSize, format, dataSpace, rotation, setId),
mTotalBufferCount(0),
mHandoutTotalBufferCount(0),
mHandoutOutputBufferCount(0),
mFrameCount(0),
mLastTimestamp(0) {
mCombinedFence = new Fence();
}
Camera3Stream::Camera3Stream(int id,
camera3_stream_type type,
uint32_t width, uint32_t height, size_t maxSize, int format,
android_dataspace dataSpace, camera3_stream_rotation_t rotation, int setId) :
camera3_stream(),
mId(id),
mSetId(setId),
mName(String8::format("Camera3Stream[%d]", id)),
mMaxSize(maxSize),
mState(STATE_CONSTRUCTED),
mStatusId(StatusTracker::NO_STATUS_ID),
mStreamUnpreparable(true),
mUsage(0),
mOldUsage(0),
mOldMaxBuffers(0),
mPrepared(false),
mPreparedBufferIdx(0),
mLastMaxCount(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX),
mBufferLimitLatency(kBufferLimitLatencyBinSize),
mFormatOverridden(false),
mOriginalFormat(-1) {
camera3_stream::stream_type = type;
camera3_stream::width = width;
camera3_stream::height = height;
camera3_stream::format = format;
camera3_stream::data_space = dataSpace;
camera3_stream::rotation = rotation;
camera3_stream::max_buffers = 0;
camera3_stream::priv = NULL;
}
最后形成一个camera3_steam_t?
hardware/libhardware/include/hardware/camera3.h
/**
* camera3_stream_t:
*
* A handle to a single camera input or output stream. A stream is defined by
* the framework by its buffer resolution and format, and additionally by the
* HAL with the gralloc usage flags and the maximum in-flight buffer count.
*
* The stream structures are owned by the framework, but pointers to a
* camera3_stream passed into the HAL by configure_streams() are valid until the
* end of the first subsequent configure_streams() call that _does not_ include
* that camera3_stream as an argument, or until the end of the close() call.
*
* All camera3_stream framework-controlled members are immutable once the
* camera3_stream is passed into configure_streams(). The HAL may only change
* the HAL-controlled parameters during a configure_streams() call, except for
* the contents of the private pointer.
*
* If a configure_streams() call returns a non-fatal error, all active streams
* remain valid as if configure_streams() had not been called.
*/
创建steam后mRemoteDevice.endConfigure(operatingMode);
binder::Status CameraDeviceClient::endConfigure(int operatingMode) {
mDevice->configureStreams(operatingMode);
}
status_t Camera3Device::configureStreams(int operatingMode) {
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
return configureStreamsLocked(operatingMode);
}
status_t Camera3Device::configureStreamsLocked(int operatingMode) {
camera3_stream_configuration config;
config.operation_mode = mOperatingMode;
config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
Vector<camera3_stream_t*> streams;
streams.setCapacity(config.num_streams);
for (size_t i = 0; i < mOutputStreams.size(); i++) {
camera3_stream_t *outputStream;
outputStream = mOutputStreams.editValueAt(i)->startConfiguration();
streams.add(outputStream);
}
// Do the HAL configuration; will potentially touch stream
// max_buffers, usage, priv fields.
res = mInterface->configureStreams(&config);
for (size_t i = 0; i < mOutputStreams.size(); i++) {
sp<Camera3OutputStreamInterface> outputStream =
mOutputStreams.editValueAt(i);
if (outputStream->isConfiguring() && !outputStream->isConsumerConfigurationDeferred()) {
res = outputStream->finishConfiguration(); /*有关consumer相关的操作*/
}
}
// Request thread needs to know to avoid using repeat-last-settings protocol
// across configure_streams() calls
mRequestThread->configurationComplete(mIsConstrainedHighSpeedConfiguration);
}
status_t Camera3Stream::finishConfiguration() {
configureQueueLocked();
mState = STATE_CONFIGURED;
return res;
}
status_t Camera3OutputStream::configureQueueLocked() {
status_t res;
mTraceFirstBuffer = true;
if ((res = Camera3IOStreamBase::configureQueueLocked()) != OK) {
return res;
}
if ((res = configureConsumerQueueLocked()) != OK) {
return res;
}
return OK;
}
status_t Camera3OutputStream::configureConsumerQueueLocked() {
// Configure consumer-side ANativeWindow interface. The listener may be used
// to notify buffer manager (if it is used) of the returned buffers.
res = mConsumer->connect(NATIVE_WINDOW_API_CAMERA,
/*listener*/mBufferReleasedListener,
/*reportBufferRemoval*/true);
native_window_set_usage/native_window_set_scaling_mode/
native_window_set_buffers_dimensions/native_window_set_buffers_format
native_window_set_buffers_data_space/native_window_set_buffer_count
}