Skip to content

Commit

Permalink
core: Add ZSL stream configuration
Browse files Browse the repository at this point in the history
Add a ConfigureZsl() helper that configures libcamera for zero shutter
lag operating mode.  This sets up a full resolution stills capture
stream, a viewfinder stream, and an optional raw stream.

Signed-off-by: Naushir Patuck <[email protected]>
  • Loading branch information
naushir committed Oct 19, 2023
1 parent 28b2a4f commit eb4c7a0
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 0 deletions.
95 changes: 95 additions & 0 deletions core/libcamera_app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,101 @@ void LibcameraApp::ConfigureViewfinder()
LOG(2, "Viewfinder setup complete");
}

void LibcameraApp::ConfigureZsl(unsigned int still_flags)
{
LOG(2, "Configuring ZSL...");

StreamRoles stream_roles = { StreamRole::StillCapture, StreamRole::Viewfinder };
if (!options_->no_raw)
stream_roles.push_back(StreamRole::Raw);

configuration_ = camera_->generateConfiguration(stream_roles);
if (!configuration_)
throw std::runtime_error("failed to generate viewfinder configuration");

// Now we get to override any of the default settings from the options_->
if (still_flags & FLAG_STILL_BGR)
configuration_->at(0).pixelFormat = libcamera::formats::BGR888;
else if (still_flags & FLAG_STILL_RGB)
configuration_->at(0).pixelFormat = libcamera::formats::RGB888;
else
configuration_->at(0).pixelFormat = libcamera::formats::YUV420;
if (options_->buffer_count > 0)
configuration_->at(0).bufferCount = options_->buffer_count;
else
// Use the viewfinder stream buffer count if none has been provided
configuration_->at(0).bufferCount = configuration_->at(1).bufferCount;
if (options_->width)
configuration_->at(0).size.width = options_->width;
if (options_->height)
configuration_->at(0).size.height = options_->height;
configuration_->at(0).colorSpace = libcamera::ColorSpace::Sycc;
configuration_->transform = options_->transform;

post_processor_.AdjustConfig("still", &configuration_->at(0));

if (!options_->no_raw)
{
options_->mode.update(configuration_->at(0).size, options_->framerate);
options_->mode = selectMode(options_->mode);

configuration_->at(2).size = options_->mode.Size();
configuration_->at(2).pixelFormat = mode_to_pixel_format(options_->mode);
configuration_->sensorConfig = libcamera::SensorConfiguration();
configuration_->sensorConfig->outputSize = options_->mode.Size();
configuration_->sensorConfig->bitDepth = options_->mode.bit_depth;
configuration_->at(2).bufferCount = configuration_->at(0).bufferCount;
}

Size size(1280, 960);
auto area = camera_->properties().get(properties::PixelArrayActiveAreas);
if (options_->viewfinder_width && options_->viewfinder_height)
size = Size(options_->viewfinder_width, options_->viewfinder_height);
else if (area)
{
// The idea here is that most sensors will have a 2x2 binned mode that
// we can pick up. If it doesn't, well, you can always specify the size
// you want exactly with the viewfinder_width/height options_->
size = (*area)[0].size() / 2;
// If width and height were given, we might be switching to capture
// afterwards - so try to match the field of view.
if (options_->width && options_->height)
size = size.boundedToAspectRatio(Size(options_->width, options_->height));
size.alignDownTo(2, 2); // YUV420 will want to be even
LOG(2, "Viewfinder size chosen is " << size.toString());
}

// Finally trim the image size to the largest that the preview can handle.
Size max_size;
preview_->MaxImageSize(max_size.width, max_size.height);
if (max_size.width && max_size.height)
{
size.boundTo(max_size.boundedToAspectRatio(size)).alignDownTo(2, 2);
LOG(2, "Final viewfinder size is " << size.toString());
}

// Now we get to override any of the default settings from the options_->
configuration_->at(1).pixelFormat = libcamera::formats::YUV420;
configuration_->at(1).size = size;
configuration_->at(1).bufferCount = configuration_->at(0).bufferCount;

configuration_->transform = options_->transform;

post_processor_.AdjustConfig("viewfinder", &configuration_->at(1));

configureDenoise(options_->denoise == "auto" ? "cdn_hq" : options_->denoise);
setupCapture();

streams_["still"] = configuration_->at(0).stream();
streams_["viewfinder"] = configuration_->at(1).stream();
if (!options_->no_raw)
streams_["raw"] = configuration_->at(2).stream();

post_processor_.Configure();

LOG(2, "ZSL setup complete");
}

void LibcameraApp::ConfigureStill(unsigned int flags)
{
LOG(2, "Configuring still capture...");
Expand Down
1 change: 1 addition & 0 deletions core/libcamera_app.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ class LibcameraApp
void ConfigureViewfinder();
void ConfigureStill(unsigned int flags = FLAG_STILL_NONE);
void ConfigureVideo(unsigned int flags = FLAG_VIDEO_NONE);
void ConfigureZsl(unsigned int still_flags = FLAG_STILL_NONE);

void Teardown();
void StartCamera();
Expand Down
4 changes: 4 additions & 0 deletions core/still_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ struct StillOptions : public Options
"Perform first capture immediately, with no preview phase")
("autofocus-on-capture", value<bool>(&af_on_capture)->default_value(false)->implicit_value(true),
"Switch to AfModeAuto and trigger a scan just before capturing a still")
("zsl", value<bool>(&zsl)->default_value(false)->implicit_value(true),
"Switch to AfModeAuto and trigger a scan just before capturing a still")
;
// clang-format on
}
Expand All @@ -67,6 +69,7 @@ struct StillOptions : public Options
bool raw;
std::string latest;
bool immediate;
bool zsl;

virtual bool Parse(int argc, char *argv[]) override
{
Expand Down Expand Up @@ -114,6 +117,7 @@ struct StillOptions : public Options
std::cerr << " latest: " << latest << std::endl;
std::cerr << " immediate " << immediate << std::endl;
std::cerr << " AF on capture: " << af_on_capture << std::endl;
std::cerr << " Zero shutter lag: " << zsl << std::endl;
for (auto &s : exif)
std::cerr << " EXIF: " << s << std::endl;
}
Expand Down

0 comments on commit eb4c7a0

Please sign in to comment.