@@ -8,6 +8,7 @@
#include <algorithm>
#include <array>
#include <iomanip>
+#include <map>
#include <memory>
#include <numeric>
#include <queue>
@@ -173,7 +174,7 @@ private:
int initLinks(Camera *camera, const CameraSensor *sensor,
const RkISP1CameraConfiguration &config);
int createCamera(MediaEntity *sensor);
- void tryCompleteRequest(RkISP1FrameInfo *info);
+ void tryCompleteRequest(Request *request);
void bufferReady(FrameBuffer *buffer);
void statReady(FrameBuffer *buffer);
void frameStart(uint32_t sequence);
@@ -197,6 +198,7 @@ private:
std::vector<std::unique_ptr<FrameBuffer>> statBuffers_;
std::queue<FrameBuffer *> availableParamBuffers_;
std::queue<FrameBuffer *> availableStatBuffers_;
+ std::map<int, FrameBuffer *> inFlightStatBuffers_;
Camera *activeCamera_;
@@ -229,6 +231,7 @@ RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *req
paramBuffer = pipe_->availableParamBuffers_.front();
pipe_->availableParamBuffers_.pop();
+ paramBuffer->_d()->setRequest(request);
statBuffer = pipe_->availableStatBuffers_.front();
pipe_->availableStatBuffers_.pop();
@@ -425,8 +428,9 @@ void RkISP1CameraData::metadataReady(unsigned int bufferId,
info->request->metadata().merge(metadata);
info->metadataProcessed = true;
+ pipe()->inFlightStatBuffers_.erase(info->request->sequence());
- pipe()->tryCompleteRequest(info);
+ pipe()->tryCompleteRequest(statBuffer->request());
return;
}
@@ -1044,6 +1048,8 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)
if (!info)
return -ENOENT;
+ inFlightStatBuffers_[request->sequence()] = info->statBuffer;
+
data->ipa_->queueRequest(request->sequence(), request->controls());
if (isRaw_) {
if (info->mainPathBuffer)
@@ -1245,15 +1251,19 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
* Buffer Handling
*/
-void PipelineHandlerRkISP1::tryCompleteRequest(RkISP1FrameInfo *info)
+void PipelineHandlerRkISP1::tryCompleteRequest(Request *request)
{
RkISP1CameraData *data = cameraData(activeCamera_);
- Request *request = info->request;
+
+ RkISP1FrameInfo *info = data->frameInfo_.find(request);
+ if (!info)
+ return;
if (request->hasPendingBuffers())
return;
- if (!info->metadataProcessed)
+ if (inFlightStatBuffers_.find(request->sequence()) !=
+ inFlightStatBuffers_.end())
return;
data->frameInfo_.destroy(info->frame);
@@ -1295,7 +1305,7 @@ void PipelineHandlerRkISP1::bufferReady(FrameBuffer *buffer)
}
completeBuffer(request, buffer);
- tryCompleteRequest(info);
+ tryCompleteRequest(request);
}
void PipelineHandlerRkISP1::statReady(FrameBuffer *buffer)
@@ -1310,7 +1320,8 @@ void PipelineHandlerRkISP1::statReady(FrameBuffer *buffer)
if (buffer->metadata().status == FrameMetadata::FrameCancelled) {
info->metadataProcessed = true;
- tryCompleteRequest(info);
+ inFlightStatBuffers_.erase(request->sequence());
+ tryCompleteRequest(request);
return;
}
tryCompleteRequest() is used to delay completeRequest() until all the image buffers have been returned to userspace and the Request's metadata has been filled with control values by the IPA. To do that the pipeline handler has a struct which holds various pieces of info that allow the tryCompleteRequest() function to decide whether it's ok to complete the request yet or not. This is quite a heavy way of doing things - most of the information is tracked internally in the Request already (status of the image buffers), some doesn't actually factor into the decision (whether the next param buffer is dequeued) and the final piece (the status of the statistics buffer) can be tracked more simply with a map. Re-factor the tryCompleteRequest() function to take a Request * and simply check hasPendingBuffers(request) and a new map flagging stats buffers as in-flight to decide whether or not to complete. Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com> --- As an alternative to the inFlightStatBuffers_ map we could instead extend Request with a concept of internal-only buffers, probably in Request::Private, that wouldn't be exposed to the application but which could be added with an analogue of addBuffer() and checked with an analogue of hasPendingBuffers(). src/libcamera/pipeline/rkisp1/rkisp1.cpp | 25 +++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)