1
可以认为,创建会话是预览的第一步。上一章节单独开来,以免这内容过多。
2
之后,需要下发抓图命令设置
看过上一章会大概知道各个框架的结构,所以下发命令会更容易看懂
应用AndroidCameraDeviceProxy::createCaptureRequest里面调用mCameraDevice.createCaptureRequest
具体实现在CameraDeviceImpl::createCaptureRequest()进入framework
这里调用简单贴下过程,创建CaptureRequest
1.CaptureRequest.Builder createCaptureRequest
2.mRemoteDevice.createDefaultRequest
2.CameraDeviceClient::createDefaultRequest
3.mDevice->createDefaultRequest
3.Camera3Device::createDefaultRequest
4.mInterface->constructDefaultRequestSettings
4Camera3Device::HalInterface::constructDefaultRequestSettings
5.mHidlSession->constructDefaultRequestSettings
6.mParent->constructDefaultRequestSettings
6.CameraDeviceSession::constructDefaultRequestSettings
7.mDevice->ops->construct_default_request_settings
这个其实是设置默认request的设置
3
接下来看capture的数据是怎么显示的,这个是重点。
预览会调用CameraDeviceImpl的capture和setRepeatingRequest函数
调用mRemoteDevice.submitRequestList也就是调用
ICameraDeviceUserWrapper:: submitRequestList
public SubmitInfo submitRequest(CaptureRequest[] requestList,, boolean streaming)
throws CameraAccessException {
try {
return mRemoteDevice. submitRequestList (requestList, streaming);
调用
binder::Status CameraDeviceClient::submitRequestList(
const std::vector<hardware::camera2::CaptureRequest>& requests,
bool streaming,
/*out*/
hardware::camera2::utils::SubmitInfo *submitInfo) {
……
else {
for (size_t i = 0; i < request.mStreamIdxList.size(); i++) {
int streamId = request.mStreamIdxList.itemAt(i);
int surfaceIdx = request.mSurfaceIdxList.itemAt(i);
ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
……
const auto& gbps = mConfiguredOutputs.valueAt(index).getGraphicBufferProducers();
……//添加surfaceMap
res = insertGbpLocked(gbps[surfaceIdx], &surfaceMap, &outputStreamIds, nullptr);
......
}
surfaceMapList.push_back(surfaceMap);//保存到列表
……//预览调用函数
err = mDevice->setStreamingRequestList(metadataRequestList, surfaceMapList,
调用
Camera3Device::setStreamingRequestList
不过不管拍照还是预览,都调用submitRequestsHelper,值是repeating那个参数不一致
submitRequestsHelper(requestsList, surfaceMaps, /*repeating*/true, lastFrameNumber);
status_t Camera3Device::submitRequestsHelper(
const List<const PhysicalCameraSettingsList> &requests,
const std::list<const SurfaceMap> &surfaceMaps,
bool repeating,
/*out*/
int64_t *lastFrameNumber) {
……
res = convertMetadataListToRequestListLocked(requests, surfaceMaps,
repeating, /*out*/&requestList);//3.1
……
if (repeating) {
res = mRequestThread->setRepeatingRequests(requestList, lastFrameNumber);//3.3
} else {
res = mRequestThread->queueRequestList(requestList, lastFrameNumber);//3.2
}
3.1
//函数转换metadata 指定surface
status_t Camera3Device::convertMetadataListToRequestListLocked(
const List &metadataList,
const std::list &surfaceMaps,
bool repeating,
RequestList *requestList) {
……
for (; metadataIt != metadataList.end() && surfaceMapIt != surfaceMaps.end();
++metadataIt, ++surfaceMapIt) {
sp newRequest = setUpRequestLocked(*metadataIt, *surfaceMapIt);//当然可以继续看下
……
requestList->push_back(newRequest);
……
}
3.2
mRequestThread->queueRequestList
status_t Camera3Device::RequestThread::queueRequestList(
List<sp > &requests,
/out/
int64_t *lastFrameNumber) {
ATRACE_CALL();
Mutex::Autolock l(mRequestLock);
for (List<sp >::iterator it = requests.begin(); it != requests.end();
++it) {
mRequestQueue.push_back(*it);//添加到mRequestQueue
}
……
unpauseForNewRequests();//执行mRequestSignal.signal();发送信号量
3.3
status_t Camera3Device::RequestThread::setRepeatingRequests(
const RequestList &requests,
/out/
int64_t *lastFrameNumber) {
……
mRepeatingRequests.insert(mRepeatingRequests.begin(),
requests.begin(), requests.end());
unpauseForNewRequests();//signal唤醒
//这个是添加到mRepeatingRequests
4
现在分析下RequestThread做的事情,这个是在创建Camera3Device的时候初始化并运行的,上节有讲到。
Camera3Device::RequestThread::threadLoop() {
……
// Wait for the next batch of requests.
waitForNextRequestBatch();//从mRequestQueue拿request,代码里看的出来是优先让mRequestQueue入队
……
// Prepare a batch of HAL requests and output buffers., 请求信息填充以及buffer申请
res = prepareHalRequests();//4.1
……
if (mInterface->supportBatchRequest()) {
submitRequestSuccess = sendRequestsBatch();
} else {
submitRequestSuccess = sendRequestsOneByOne();//4.2
}
4.1
主要给halRequest赋值
status_t Camera3Device::RequestThread::prepareHalRequests() {
ATRACE_CALL();
for (size_t i = 0; i < mNextRequests.size(); i++) {
auto& nextRequest = mNextRequests.editItemAt(i);
sp<CaptureRequest> captureRequest = nextRequest.captureRequest;
camera3_capture_request_t* halRequest = &nextRequest.halRequest;
Vector<camera3_stream_buffer_t>* outputBuffers = &nextRequest.outputBuffers;
......
for (size_t j = 0; j < captureRequest->mOutputStreams.size(); j++) {
sp<Camera3OutputStreamInterface> outputStream = captureRequest->mOutputStreams.editItemAt(j);
......
// 这里将会根据当前请求配置的 surfaces id 获取surfaces buffer
res = outputStream->getBuffer(&outputBuffers->editItemAt(j),
captureRequest->mOutputSurfaces[j]);
......
}
Camera3Stream::getBuffer
getBufferLocked(buffer, surface_ids);
Camera3OutputStream::getBufferLocked 里面调用handoutBufferLocked(*buffer, &(anb->handle),将anb的handle赋值给buffer的同类变量。
getBufferLockedCommon(&anb, &fenceFd);
Camera3OutputStream::getBufferLockedCommon
status_t Camera3OutputStream::getBufferLockedCommon(ANativeWindowBuffer** anb, int* fenceFd) {
……// mConsumer是在创建Camera3OutputStream传下来的surface,
sp<ANativeWindow> currentConsumer = mConsumer;
……//类似原先在hal1里面实现的,dequeueBuffer现在放到service里来实现,生产者请求一个buffer,
//真正的buffer是在这里申请,着个函数应该也是走gralloc
res = currentConsumer->dequeueBuffer(currentConsumer.get(), anb, fenceFd);
4.2
bool Camera3Device::RequestThread::sendRequestsOneByOne() {
......
for (auto& nextRequest : mNextRequests) {
/* 将请求信息传递到 CameraProvider 处理 */
res = mInterface->processCaptureRequest(&nextRequest.halRequest);
......
}
}
CameraDeviceSession::processCaptureRequest
processOneCaptureRequest
status_t ret = mDevice->ops->process_capture_request(mDevice, &halRequest);
进入到hal
发送抓取数据命令下去,hal会用mCallbackOps->notify()、mCallbackOps->process_capture_result()返回抓取的时间以及metadata和buffer数据。
那么回头查找设置mCallbackOps的时候
bool CameraDeviceSession::initialize() {
/** Initialize device with callback functions */
ATRACE_BEGIN("camera3->initialize");
status_t res = mDevice->ops->initialize(mDevice, this);//传入的mCallbackOps是this(CameraDeviceSession)
所以回调执行
void CameraDeviceSession::sNotify(
const camera3_callback_ops *cb,
const camera3_notify_msg *msg) {
CameraDeviceSession *d =
const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
NotifyMsg hidlMsg;
convertToHidl(msg, &hidlMsg);
……
d->mResultBatcher.notify(hidlMsg);//对返回事件检查后调用
mResultBatcher查找下赋值的地方
CameraDeviceSession::CameraDeviceSession(
camera3_device_t* device,
const camera_metadata_t* deviceInfo,
const sp<ICameraDeviceCallback>& callback) :
camera3_callback_ops({&sProcessCaptureResult, &sNotify}),
mDevice(device),
mDeviceVersion(device->common.version),
mFreeBufEarly(shouldFreeBufEarly()),
mIsAELockAvailable(false),
mDerivePostRawSensKey(false),
mNumPartialResults(1),
mResultBatcher(callback) {//是callback,继续往上查找参数
一直往上看,就是在open的时候
Camera3Device::initialize函数里
manager->openSession(mId.string(), this,/out/ &session);//这个this就是callback,也就是mResultBatcher是Camera3Device
manager->openSession
CameraProviderManager::openSession
deviceInfo3->mInterface->open(callback, [&status, &session]
CameraDevice::open
createSession(device, info.static_camera_characteristics, callback);
CameraDevice::createSession
CameraDeviceSession(device, deviceInfo, callback);
Camera3Device::Camera3Device(const String8 &id)
camera3_callback_ops::notify = &sNotify;
camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
所以最终执行到Camera3Device::notify
case CAMERA3_MSG_SHUTTER: {
notifyShutter(msg->message.shutter, listener);
函数调用listener->notifyShutter(r.resultExtras, msg.timestamp);
执行到CameraDeviceClient::notifyShutter
一步步到上层,还是接着看下面的buffer吧
CameraDeviceSession::sProcessCaptureResult
d->mResultBatcher.processCaptureResult(result);//同样执行到
Camera3Device::processCaptureResult
returnOutputBuffers
Camera3Device::processCaptureResult() —> stream->returnBuffer()
Camera3Stream::returnBuffer() —> returnBufferLocked()
Camera3OutputStream::returnBufferLocked() —> returnAnyBufferLocked( , , true)
Camera3IOStreamBase::returnAnyBufferLocked() —> returnBufferCheckedLocked()
Camera3OutputStream::returnBufferCheckedLocked()
看看实现
status_t Camera3OutputStream::returnBufferCheckedLocked(
const camera3_stream_buffer &buffer,
nsecs_t timestamp,
bool output,
/*out*/
sp<Fence> *releaseFenceOut) {
……
sp<ANativeWindow> currentConsumer = mConsumer;
……
queueBufferToConsumer(currentConsumer, anwBuffer, anwReleaseFence);
实现
status_t Camera3OutputStream::queueBufferToConsumer(sp& consumer,
ANativeWindowBuffer* buffer, int anwReleaseFence) {
return consumer->queueBuffer(consumer.get(), buffer, anwReleaseFence);
}
在queueBuffer() 之后,buffer 将可以通过 Surface 显示出来了
后续简单再理解下:
createCaptureSession(List outputs,
CameraCaptureSession.StateCallback callback, Handler handler)
传入的是Surface,简单的把他理解为从Surface为数据的创造着,所以,摄像头输出往这里面填,然后由finger混合显示
CameraDeviceClient:: createStream
Camera3Device:: createStream
Camera3OutputStream
Camera3IOStreamBase
Camera3Stream 一路这么创建下去.
创建完后,调用mRemoteDevice.endConfigure
CameraDeviceClient::endConfigure,第一个参数是normal模式,第二个为null
直接执行mDevice->configureStreams
filterParamsAndConfigureLocked
configureStreamsLocked
CameraDeviceSession::configureStreams_3_3 执行配置
为了返回seesion,要new 一个CameraCaptureSessionImpl 作为返回值,在构造函数里调用mStateCallback.onConfigured(this)
作为返回创建的结构。
实际上createCaptureSession并没有什么逻辑结构。都是简单调用。
下发request信息
ICameraDeviceUserWrapper::submitRequest
mRemoteDevice.submitRequestLis
setStreamingRequestList
submitRequestsHelper
mRequestThread->setRepeatingRequests 发消息,发送消息前有个转换convertMetadataListToRequestListLocked{
const List &metadataList,
const std::list &surfaceMaps,
bool repeating,
RequestList *requestList)
第一个参数是metadata,这个是由应用的CaptureRequest里面的mPhysicalCameraSettings。应用Req里面包含了metadata。
Requestthread做的事
- 获取nextrequest
- 请求信息填充buffer申请
- sendRequestsOneByOne
CameraDeviceSession::sProcessCaptureResult是返回数据的函数
mResultBatcher.processCaptureResult(result);
Camera3Device::processCaptureResult
stream->returnBuffer()
Camera3Stream::returnBuffer
returnBufferLocked
Camera3OutputStream::returnBufferLocked
returnAnyBufferLocked
Camera3IOStreamBase::returnAnyBufferLocked
returnBufferCheckedLocked
Camera3OutputStream::returnBufferCheckedLocked
queueBufferToConsumer
Camera3OutputStream::queueBufferToConsumer
consumer->queueBuffer
这样buffer就被显示出来