libcamera: pipeline: Add test pattern for VirtualPipelineHandler

Add a test pattern generator class hierarchy for the Virtual
pipeline handler.

Implement two types of test patterns: color bars and diagonal lines
generator and use them in the Virtual pipeline handler.

A shifting mechanism is enabled. For each frame, the image is shifted to
the left by 1 pixel. It drops FPS though.

Add a dependency for libyuv to the build system to generate images
in NV12 format from the test pattern.

Signed-off-by: Konami Shu <konamiz@google.com>
Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>
Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Co-developed-by: Yunke Cao <yunkec@chromium.org>
Signed-off-by: Yunke Cao <yunkec@chromium.org>
Co-developed-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Harvey Yang
2024-10-22 07:43:40 +00:00
committed by Kieran Bingham
parent 3a884ebfe4
commit eeaa7de21b
8 changed files with 282 additions and 22 deletions
+38 -3
View File
@@ -34,6 +34,7 @@
#include "libcamera/internal/camera.h"
#include "libcamera/internal/dma_buf_allocator.h"
#include "libcamera/internal/formats.h"
#include "libcamera/internal/framebuffer.h"
#include "libcamera/internal/pipeline_handler.h"
namespace libcamera {
@@ -94,6 +95,8 @@ private:
return static_cast<VirtualCameraData *>(camera->_d());
}
void initFrameGenerator(Camera *camera);
DmaBufAllocator dmaBufAllocator_;
bool resetCreated_ = false;
@@ -241,8 +244,10 @@ int PipelineHandlerVirtual::configure(Camera *camera,
CameraConfiguration *config)
{
VirtualCameraData *data = cameraData(camera);
for (auto [i, c] : utils::enumerate(*config))
for (auto [i, c] : utils::enumerate(*config)) {
c.setStream(&data->streamConfigs_[i].stream);
data->streamConfigs_[i].frameGenerator->configure(c.size);
}
return 0;
}
@@ -278,8 +283,24 @@ void PipelineHandlerVirtual::stopDevice([[maybe_unused]] Camera *camera)
int PipelineHandlerVirtual::queueRequestDevice([[maybe_unused]] Camera *camera,
Request *request)
{
for (auto it : request->buffers())
completeBuffer(request, it.second);
VirtualCameraData *data = cameraData(camera);
for (auto const &[stream, buffer] : request->buffers()) {
bool found = false;
/* map buffer and fill test patterns */
for (auto &streamConfig : data->streamConfigs_) {
if (stream == &streamConfig.stream) {
found = true;
if (streamConfig.frameGenerator->generateFrame(
stream->configuration().size, buffer))
buffer->_d()->cancel();
completeBuffer(request, buffer);
break;
}
}
ASSERT(found);
}
request->metadata().set(controls::SensorTimestamp, currentTimestamp());
completeRequest(request);
@@ -325,6 +346,9 @@ bool PipelineHandlerVirtual::match([[maybe_unused]] DeviceEnumerator *enumerator
const std::string id = "Virtual0";
std::shared_ptr<Camera> camera = Camera::create(std::move(data), id, streams);
initFrameGenerator(camera.get());
registerCamera(std::move(camera));
resetCreated_ = true;
@@ -332,6 +356,17 @@ bool PipelineHandlerVirtual::match([[maybe_unused]] DeviceEnumerator *enumerator
return true;
}
void PipelineHandlerVirtual::initFrameGenerator(Camera *camera)
{
auto data = cameraData(camera);
for (auto &streamConfig : data->streamConfigs_) {
if (data->testPattern_ == TestPattern::DiagonalLines)
streamConfig.frameGenerator = std::make_unique<DiagonalLinesGenerator>();
else
streamConfig.frameGenerator = std::make_unique<ColorBarsGenerator>();
}
}
REGISTER_PIPELINE_HANDLER(PipelineHandlerVirtual, "virtual")
} /* namespace libcamera */