camera2 outputbuffer的流转过程
camera2 outputbuffer 流转
1、cameraserver下发buffer请求到camera hal
1.1、android系统中 camera app下发 setRepeatingRequests 请求后,会将requests 参数给到mRepeatingRequests
status_t Camera3Device::RequestThread::setRepeatingRequests(const RequestList &requests, // 这里是app下发请求带下来的/*out*/int64_t *lastFrameNumber) {ATRACE_CALL();Mutex::Autolock l(mRequestLock);if (lastFrameNumber != NULL) {*lastFrameNumber = mRepeatingLastFrameNumber;}mRepeatingRequests.clear();mFirstRepeating = true;mRepeatingRequests.insert(mRepeatingRequests.begin(),requests.begin(), requests.end()); // 将requests给到mRepeatingRequestsunpauseForNewRequests();mRepeatingLastFrameNumber = hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES;return OK;
}
调用setRepeatingRequests之后,之前创建处于wait的Camera3Device::RequestThread::threadLoop() 线程就会被激活, 就会调用 prepareHalRequests() 去创建request, 然后下发给hal
Camera3Device::RequestThread::threadLoop() {......// Prepare a batch of HAL requests and output buffers.res = prepareHalRequests();......
}Camera3Device::RequestThread::prepareHalRequests() {for (size_t i = 0; i < mNextRequests.size(); i++) {auto& nextRequest = mNextRequests.editItemAt(i);sp<CaptureRequest> captureRequest = nextRequest.captureRequest;// 这里就是向hal发送的request请求,目前还是指针类型,还需要填充要下发的内容camera_capture_request_t* halRequest = &nextRequest.halRequest;// 这里先获取outputBuffers指针Vector<camera_stream_buffer_t>* outputBuffers = &nextRequest.outputBuffers;.......//看看后面如何给outputBuffers分配bufferoutputBuffers->insertAt(camera_stream_buffer_t(), 0,captureRequest->mOutputStreams.size()); //将outputBuffers指针给了halRequest->output_buffershalRequest->output_buffers = outputBuffers->array(); std::set<std::set<String8>> requestedPhysicalCameras;......// 获取buffer,这里outputStream是在app创建会话的时候,调用到configureStreamsLocked()// 创建好的,这里的outputStream要怎么理解呢// “这个请求生成的图像,要分别送到这些“目标通道”中去 —— 比如送到预览界面(Preview Surface)、录制视频的 Surface、图像编码输出的 Surface 等。”for (size_t j = 0; j < captureRequest->mOutputStreams.size(); j++) {sp<Camera3OutputStreamInterface> outputStream = captureRequest->mOutputStreams.editItemAt(j);res = outputStream->getBuffer(&outputBuffers->editItemAt(j),waitDuration,captureRequest->mOutputSurfaces[streamId]);}}
}//
status_t Camera3OutputStream::getBufferLocked(camera_stream_buffer *buffer,const std::vector<size_t>&) {ATRACE_HFR_CALL();ANativeWindowBuffer* anb;int fenceFd = -1;status_t res;res = getBufferLockedCommon(&anb, &fenceFd);if (res != OK) {return res;}// 实际可写入的 buffer 句柄,就是 gralloc 分配出来的 buffer/*** FenceFD now owned by HAL except in case of error,* in which case we reassign it to acquire_fence*/handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,/*releaseFence*/-1, CAMERA_BUFFER_STATUS_OK, /*output*/true);return OK;
}Camera3OutputStream::getBufferLockedCommon(ANativeWindowBuffer** anb, int* fenceFd) {......sp<ANativeWindow> anw = consumer;// 这些 buffer 就是通过 ANativeWindow(实际是 Surface)从图像缓冲队列(BufferQueue)中 dequeue 出来的一个空buffer,用于给hal填充数据的res = anw->dequeueBuffer(anw.get(), anb, fenceFd);......
}Surface::dequeueBuffers(std::vector<BatchBuffer>* buffers) {......// 从 GraphicBufferProducer中去获取空闲的gralloc 分配出来的 buffermGraphicBufferProducer->dequeueBuffers(dequeueInput, &dequeueOutput);......}void Camera3IOStreamBase::handoutBufferLocked(camera_stream_buffer &buffer,buffer_handle_t *handle,int acquireFence,int releaseFence,camera_buffer_status_t status,bool output) {// 这里实际可写入的 buffer 句柄,就是 gralloc 分配出来的 buffer。......buffer.buffer = handle;..... }
通过上面拿到buffer后,下发给camera hal
buffer 实际来源:App 创建的 Surface(如 SurfaceView, ImageReader, MediaRecorder 等),这些 Surface 最终通过 IGraphicBufferProducer 接口传给 HAL。
buffer 个数限制:由 GraphicBufferQueue 控制,一般来说 default 是 maxDequeuedBufferCount + maxAcquiredBufferCount,常见为 3 ~ 5 个。
mConsumer = 应用传入的 Surface,是 HAL 获取和返回 buffer 的出口。
使用 mConsumer->dequeueBuffer() 拿到空白 buffer,由 HAL 写入图像数据。
使用 mConsumer->queueBuffer() 把写好的 buffer 返还给 SurfaceFlinger 或应用。
2、camera hal 填充buffer return result 到cameraserver
这里涉及到hal的实现了,各个厂商有自己的实现方式,我不能暴露太多我们的代码,我大概说一下流程,实现流程通过process_capture_request调用到hal后,会继续在 hal实现process_capture_request的功能,以下是hal 填充output_buffer的流程,填充完了之后会返回给app
static int process_capture_request(const camera3_device_t *dev,camera3_capture_request_t *request)
{return camdev_to_camera(dev)->processCaptureRequest(request);
}
3、cameraserver 上屏显示camera data
待续。。。。