android: camera_device: Add buffers for each stream to Requests

Construct a FrameBuffer for every buffer given in the camera3Request
and add it to the libcamera Request on the appropriate stream.

The correct stream is obtained from the private data of the camera3_stream
associated with the camera3_buffer.

Comments regarding supporting only one buffer are now removed, and
FrameBuffers have their lifetime tracked in the Camera3RequestDescriptor
to ensure they are released when the Request is completed.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
This commit is contained in:
Kieran Bingham 2020-07-01 13:36:24 +01:00
parent 2f34f5ef06
commit 0cfdf737dc
2 changed files with 33 additions and 25 deletions

View file

@ -98,6 +98,7 @@ CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
: frameNumber(frameNumber), numBuffers(numBuffers) : frameNumber(frameNumber), numBuffers(numBuffers)
{ {
buffers = new camera3_stream_buffer_t[numBuffers]; buffers = new camera3_stream_buffer_t[numBuffers];
frameBuffers.reserve(numBuffers);
} }
CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor() CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor()
@ -990,6 +991,7 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
config_->addConfiguration(streamConfiguration); config_->addConfiguration(streamConfiguration);
streams_[i].index = streamIndex++; streams_[i].index = streamIndex++;
stream->priv = static_cast<void *>(&streams_[i]);
} }
switch (config_->validate()) { switch (config_->validate()) {
@ -1048,9 +1050,6 @@ FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer
int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request) int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
{ {
StreamConfiguration *streamConfiguration = &config_->at(0);
Stream *stream = streamConfiguration->stream();
if (camera3Request->num_output_buffers != 1) { if (camera3Request->num_output_buffers != 1) {
LOG(HAL, Error) << "Invalid number of output buffers: " LOG(HAL, Error) << "Invalid number of output buffers: "
<< camera3Request->num_output_buffers; << camera3Request->num_output_buffers;
@ -1088,30 +1087,36 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
camera_->createRequest(reinterpret_cast<uint64_t>(descriptor)); camera_->createRequest(reinterpret_cast<uint64_t>(descriptor));
for (unsigned int i = 0; i < descriptor->numBuffers; ++i) { for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
CameraStream *cameraStream =
static_cast<CameraStream *>(camera3Buffers[i].stream->priv);
/* /*
* Keep track of which stream the request belongs to and store * Keep track of which stream the request belongs to and store
* the native buffer handles. * the native buffer handles.
*
* \todo Currently we only support one capture buffer. Copy
* all of them to be ready once we'll support more.
*/ */
descriptor->buffers[i].stream = camera3Buffers[i].stream; descriptor->buffers[i].stream = camera3Buffers[i].stream;
descriptor->buffers[i].buffer = camera3Buffers[i].buffer; descriptor->buffers[i].buffer = camera3Buffers[i].buffer;
}
/* /*
* Create a libcamera buffer using the dmabuf descriptors of the first * Create a libcamera buffer using the dmabuf descriptors of
* and (currently) only supported request buffer. * the camera3Buffer for each stream. The FrameBuffer is
*/ * directly associated with the Camera3RequestDescriptor for
FrameBuffer *buffer = createFrameBuffer(*camera3Buffers[0].buffer); * lifetime management only.
if (!buffer) { */
LOG(HAL, Error) << "Failed to create buffer"; FrameBuffer *buffer = createFrameBuffer(*camera3Buffers[i].buffer);
delete request; if (!buffer) {
delete descriptor; LOG(HAL, Error) << "Failed to create buffer";
return -ENOMEM; delete request;
} delete descriptor;
return -ENOMEM;
}
descriptor->frameBuffers.emplace_back(buffer);
request->addBuffer(stream, buffer); StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index);
Stream *stream = streamConfiguration->stream();
request->addBuffer(stream, buffer);
}
int ret = camera_->queueRequest(request); int ret = camera_->queueRequest(request);
if (ret) { if (ret) {
@ -1127,7 +1132,6 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
void CameraDevice::requestComplete(Request *request) void CameraDevice::requestComplete(Request *request)
{ {
const std::map<Stream *, FrameBuffer *> &buffers = request->buffers(); const std::map<Stream *, FrameBuffer *> &buffers = request->buffers();
FrameBuffer *buffer = buffers.begin()->second;
camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK; camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
std::unique_ptr<CameraMetadata> resultMetadata; std::unique_ptr<CameraMetadata> resultMetadata;
@ -1145,10 +1149,6 @@ void CameraDevice::requestComplete(Request *request)
captureResult.frame_number = descriptor->frameNumber; captureResult.frame_number = descriptor->frameNumber;
captureResult.num_output_buffers = descriptor->numBuffers; captureResult.num_output_buffers = descriptor->numBuffers;
for (unsigned int i = 0; i < descriptor->numBuffers; ++i) { for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
/*
* \todo Currently we only support one capture buffer. Prepare
* all of them to be ready once we'll support more.
*/
descriptor->buffers[i].acquire_fence = -1; descriptor->buffers[i].acquire_fence = -1;
descriptor->buffers[i].release_fence = -1; descriptor->buffers[i].release_fence = -1;
descriptor->buffers[i].status = status; descriptor->buffers[i].status = status;
@ -1156,6 +1156,14 @@ void CameraDevice::requestComplete(Request *request)
captureResult.output_buffers = captureResult.output_buffers =
const_cast<const camera3_stream_buffer_t *>(descriptor->buffers); const_cast<const camera3_stream_buffer_t *>(descriptor->buffers);
/*
* \todo The timestamp used for the metadata is currently always taken
* from the first buffer (which may be the first stream) in the Request.
* It might be appropriate to return a 'correct' (as determined by
* pipeline handlers) timestamp in the Request itself.
*/
FrameBuffer *buffer = buffers.begin()->second;
if (status == CAMERA3_BUFFER_STATUS_OK) { if (status == CAMERA3_BUFFER_STATUS_OK) {
notifyShutter(descriptor->frameNumber, notifyShutter(descriptor->frameNumber,
buffer->metadata().timestamp); buffer->metadata().timestamp);
@ -1180,7 +1188,6 @@ void CameraDevice::requestComplete(Request *request)
callbacks_->process_capture_result(callbacks_, &captureResult); callbacks_->process_capture_result(callbacks_, &captureResult);
delete descriptor; delete descriptor;
delete buffer;
} }
std::string CameraDevice::logPrefix() const std::string CameraDevice::logPrefix() const

View file

@ -70,6 +70,7 @@ private:
uint32_t frameNumber; uint32_t frameNumber;
uint32_t numBuffers; uint32_t numBuffers;
camera3_stream_buffer_t *buffers; camera3_stream_buffer_t *buffers;
std::vector<std::unique_ptr<libcamera::FrameBuffer>> frameBuffers;
}; };
struct Camera3StreamConfiguration { struct Camera3StreamConfiguration {