summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2020-03-14 16:14:27 +0200
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2020-03-18 19:15:18 +0200
commit9da27d5d844fa1378a4897a637c45ade275cc7e5 (patch)
tree712a781b2134e53130bed0477e6370ad65677ecc /src
parent7d8604128ab0f11da459fdb43fd8366620afe7f5 (diff)
libcamera: pipeline_handler: Decouple buffer import and export
Use the V4L2 buffer orphaning feature, exposed through V4L2VideoDevice::exportBuffers(), to decouple buffer import and export. The PipelineHandler::importFrameBuffers() function is now called for all streams regardless of whether exportFrameBuffers() has been called or not. This simplifies the Camera implementation slightly, and opens the door to additional simplifications. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Diffstat (limited to 'src')
-rw-r--r--src/libcamera/camera.cpp21
-rw-r--r--src/libcamera/framebuffer_allocator.cpp9
-rw-r--r--src/libcamera/pipeline/ipu3/ipu3.cpp2
-rw-r--r--src/libcamera/pipeline/rkisp1/rkisp1.cpp2
-rw-r--r--src/libcamera/pipeline/uvcvideo.cpp2
-rw-r--r--src/libcamera/pipeline/vimc.cpp2
-rw-r--r--src/libcamera/pipeline_handler.cpp25
7 files changed, 10 insertions, 53 deletions
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index 9c432adb..3192dfb4 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -554,18 +554,6 @@ int Camera::exportFrameBuffers(Stream *stream,
buffers);
}
-int Camera::freeFrameBuffers(Stream *stream)
-{
- int ret = p_->isAccessAllowed(Private::CameraConfigured, true);
- if (ret < 0)
- return ret;
-
- p_->pipe_->invokeMethod(&PipelineHandler::freeFrameBuffers,
- ConnectionTypeBlocking, this, stream);
-
- return 0;
-}
-
/**
* \brief Acquire the camera device for exclusive access
*
@@ -928,9 +916,6 @@ int Camera::start()
LOG(Camera, Debug) << "Starting capture";
for (Stream *stream : p_->activeStreams_) {
- if (allocator_ && !allocator_->buffers(stream).empty())
- continue;
-
ret = p_->pipe_->invokeMethod(&PipelineHandler::importFrameBuffers,
ConnectionTypeDirect, this, stream);
if (ret < 0)
@@ -974,13 +959,9 @@ int Camera::stop()
p_->pipe_->invokeMethod(&PipelineHandler::stop, ConnectionTypeBlocking,
this);
- for (Stream *stream : p_->activeStreams_) {
- if (allocator_ && !allocator_->buffers(stream).empty())
- continue;
-
+ for (Stream *stream : p_->activeStreams_)
p_->pipe_->invokeMethod(&PipelineHandler::freeFrameBuffers,
ConnectionTypeBlocking, this, stream);
- }
return 0;
}
diff --git a/src/libcamera/framebuffer_allocator.cpp b/src/libcamera/framebuffer_allocator.cpp
index e79f4a8f..6f7a2e90 100644
--- a/src/libcamera/framebuffer_allocator.cpp
+++ b/src/libcamera/framebuffer_allocator.cpp
@@ -87,11 +87,6 @@ FrameBufferAllocator::FrameBufferAllocator(std::shared_ptr<Camera> camera)
FrameBufferAllocator::~FrameBufferAllocator()
{
- for (auto &value : buffers_) {
- Stream *stream = value.first;
- camera_->freeFrameBuffers(stream);
- }
-
buffers_.clear();
camera_->allocator_ = nullptr;
@@ -148,10 +143,6 @@ int FrameBufferAllocator::free(Stream *stream)
if (iter == buffers_.end())
return -EINVAL;
- int ret = camera_->freeFrameBuffers(stream);
- if (ret < 0)
- return ret;
-
std::vector<std::unique_ptr<FrameBuffer>> &buffers = iter->second;
buffers.clear();
buffers_.erase(iter);
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index d7eac553..2edca02e 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -621,7 +621,7 @@ int PipelineHandlerIPU3::exportFrameBuffers(Camera *camera, Stream *stream,
V4L2VideoDevice *video = ipu3stream->device_->dev;
unsigned int count = stream->configuration().bufferCount;
- return video->allocateBuffers(count, buffers);
+ return video->exportBuffers(count, buffers);
}
int PipelineHandlerIPU3::importFrameBuffers(Camera *camera, Stream *stream)
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 3734bb72..eafb6d91 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -664,7 +664,7 @@ int PipelineHandlerRkISP1::exportFrameBuffers(Camera *camera, Stream *stream,
std::vector<std::unique_ptr<FrameBuffer>> *buffers)
{
unsigned int count = stream->configuration().bufferCount;
- return video_->allocateBuffers(count, buffers);
+ return video_->exportBuffers(count, buffers);
}
int PipelineHandlerRkISP1::importFrameBuffers(Camera *camera, Stream *stream)
diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index 10597111..9876d8c9 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -211,7 +211,7 @@ int PipelineHandlerUVC::exportFrameBuffers(Camera *camera, Stream *stream,
UVCCameraData *data = cameraData(camera);
unsigned int count = stream->configuration().bufferCount;
- return data->video_->allocateBuffers(count, buffers);
+ return data->video_->exportBuffers(count, buffers);
}
int PipelineHandlerUVC::importFrameBuffers(Camera *camera, Stream *stream)
diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp
index 85f38693..097bbd5b 100644
--- a/src/libcamera/pipeline/vimc.cpp
+++ b/src/libcamera/pipeline/vimc.cpp
@@ -264,7 +264,7 @@ int PipelineHandlerVimc::exportFrameBuffers(Camera *camera, Stream *stream,
VimcCameraData *data = cameraData(camera);
unsigned int count = stream->configuration().bufferCount;
- return data->video_->allocateBuffers(count, buffers);
+ return data->video_->exportBuffers(count, buffers);
}
int PipelineHandlerVimc::importFrameBuffers(Camera *camera, Stream *stream)
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index 8d623f54..e5034c54 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -337,16 +337,7 @@ const ControlList &PipelineHandler::properties(Camera *camera)
*
* The method may only be called after the Camera has been configured and before
* it gets started, or after it gets stopped. It shall be called only for
- * streams that are part of the active camera configuration, and at most once
- * per stream until buffers for the stream are freed with freeFrameBuffers().
- *
- * exportFrameBuffers() shall also allocate all other resources required by
- * the pipeline handler for the stream to prepare for starting the Camera. This
- * responsibility is shared with importFrameBuffers(), and one and only one of
- * those two methods shall be called for each stream until the buffers are
- * freed. The pipeline handler shall support all combinations of
- * exportFrameBuffers() and importFrameBuffers() for the streams contained in
- * any camera configuration.
+ * streams that are part of the active camera configuration.
*
* The only intended caller is Camera::exportFrameBuffers().
*
@@ -371,12 +362,7 @@ const ControlList &PipelineHandler::properties(Camera *camera)
* per stream until buffers for the stream are freed with freeFrameBuffers().
*
* importFrameBuffers() shall also allocate all other resources required by the
- * pipeline handler for the stream to prepare for starting the Camera. This
- * responsibility is shared with exportFrameBuffers(), and one and only one of
- * those two methods shall be called for each stream until the buffers are
- * freed. The pipeline handler shall support all combinations of
- * exportFrameBuffers() and importFrameBuffers() for the streams contained in
- * any camera configuration.
+ * pipeline handler for the stream to prepare for starting the Camera.
*
* The only intended caller is Camera::start().
*
@@ -391,10 +377,9 @@ const ControlList &PipelineHandler::properties(Camera *camera)
* \param[in] camera The camera
* \param[in] stream The stream to free buffers for
*
- * This method shall free all buffers and all other resources allocated for the
- * \a stream by exportFrameBuffers() or importFrameBuffers(). It shall be
- * called only after a successful call to either of these two methods, and only
- * once per stream.
+ * This method shall release all resources allocated for the \a stream by
+ * importFrameBuffers(). It shall be called only after a successful call that
+ * method, and only once per stream.
*
* The only intended callers are Camera::stop() and Camera::freeFrameBuffers().
*
pan class="hl opt">= deviceStatus.shutterSpeed; parsedDeviceStatus.frameLength = deviceStatus.frameLength; metadata.set("device.status", parsedDeviceStatus); LOG(IPARPI, Debug) << "Metadata updated for long exposure: " << parsedDeviceStatus; } } std::pair<uint32_t, uint32_t> CamHelperImx519::getBlanking(Duration &exposure, Duration minFrameDuration, Duration maxFrameDuration) const { uint32_t frameLength, exposureLines; unsigned int shift = 0; auto [vblank, hblank] = CamHelper::getBlanking(exposure, minFrameDuration, maxFrameDuration); frameLength = mode_.height + vblank; Duration lineLength = hblankToLineLength(hblank); /* * Check if the frame length calculated needs to be setup for long * exposure mode. This will require us to use a long exposure scale * factor provided by a shift operation in the sensor. */ while (frameLength > frameLengthMax) { if (++shift > longExposureShiftMax) { shift = longExposureShiftMax; frameLength = frameLengthMax; break; } frameLength >>= 1; } if (shift) { /* Account for any rounding in the scaled frame length value. */ frameLength <<= shift; exposureLines = CamHelperImx519::exposureLines(exposure, lineLength); exposureLines = std::min(exposureLines, frameLength - frameIntegrationDiff); exposure = CamHelperImx519::exposure(exposureLines, lineLength); } return { frameLength - mode_.height, hblank }; } void CamHelperImx519::getDelays(int &exposureDelay, int &gainDelay, int &vblankDelay, int &hblankDelay) const { exposureDelay = 2; gainDelay = 2; vblankDelay = 3; hblankDelay = 3; } bool CamHelperImx519::sensorEmbeddedDataPresent() const { return true; } void CamHelperImx519::populateMetadata(const MdParser::RegisterMap &registers, Metadata &metadata) const { DeviceStatus deviceStatus; deviceStatus.lineLength = lineLengthPckToDuration(registers.at(lineLengthHiReg) * 256 + registers.at(lineLengthLoReg)); deviceStatus.shutterSpeed = exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg), deviceStatus.lineLength); deviceStatus.analogueGain = gain(registers.at(gainHiReg) * 256 + registers.at(gainLoReg)); deviceStatus.frameLength = registers.at(frameLengthHiReg) * 256 + registers.at(frameLengthLoReg); metadata.set("device.status", deviceStatus); } static CamHelper *create() { return new CamHelperImx519(); } static RegisterCamHelper reg("imx519", &create);