cam: Move camera configuration preparation to CamApp
Most of the camera configuration preparation that is done in the Capture module is not specific to capturing and could be useful for other modules. Extract the generic parts to CamApp and do basic preparation of the configuration before passing it to modules. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
5ed3a89480
commit
afef18d35a
3 changed files with 83 additions and 83 deletions
|
@ -15,8 +15,8 @@
|
||||||
|
|
||||||
using namespace libcamera;
|
using namespace libcamera;
|
||||||
|
|
||||||
Capture::Capture(Camera *camera)
|
Capture::Capture(Camera *camera, CameraConfiguration *config)
|
||||||
: camera_(camera), writer_(nullptr), last_(0)
|
: camera_(camera), config_(config), writer_(nullptr), last_(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,13 +29,13 @@ int Capture::run(EventLoop *loop, const OptionsParser::Options &options)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = prepareConfig(options);
|
streamName_.clear();
|
||||||
if (ret) {
|
for (unsigned int index = 0; index < config_->size(); ++index) {
|
||||||
std::cout << "Failed to prepare camera configuration" << std::endl;
|
StreamConfiguration &cfg = config_->at(index);
|
||||||
return -EINVAL;
|
streamName_[cfg.stream()] = "stream" + std::to_string(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = camera_->configure(config_.get());
|
ret = camera_->configure(config_);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
std::cout << "Failed to configure camera" << std::endl;
|
std::cout << "Failed to configure camera" << std::endl;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -64,80 +64,10 @@ int Capture::run(EventLoop *loop, const OptionsParser::Options &options)
|
||||||
}
|
}
|
||||||
|
|
||||||
camera_->freeBuffers();
|
camera_->freeBuffers();
|
||||||
config_.reset();
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Capture::prepareConfig(const OptionsParser::Options &options)
|
|
||||||
{
|
|
||||||
StreamRoles roles;
|
|
||||||
|
|
||||||
if (options.isSet(OptStream)) {
|
|
||||||
const std::vector<OptionValue> &streamOptions =
|
|
||||||
options[OptStream].toArray();
|
|
||||||
|
|
||||||
/* Use roles and get a default configuration. */
|
|
||||||
for (auto const &value : streamOptions) {
|
|
||||||
KeyValueParser::Options opt = value.toKeyValues();
|
|
||||||
|
|
||||||
if (!opt.isSet("role")) {
|
|
||||||
roles.push_back(StreamRole::VideoRecording);
|
|
||||||
} else if (opt["role"].toString() == "viewfinder") {
|
|
||||||
roles.push_back(StreamRole::Viewfinder);
|
|
||||||
} else if (opt["role"].toString() == "video") {
|
|
||||||
roles.push_back(StreamRole::VideoRecording);
|
|
||||||
} else if (opt["role"].toString() == "still") {
|
|
||||||
roles.push_back(StreamRole::StillCapture);
|
|
||||||
} else {
|
|
||||||
std::cerr << "Unknown stream role "
|
|
||||||
<< opt["role"].toString() << std::endl;
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* If no configuration is provided assume a single video stream. */
|
|
||||||
roles.push_back(StreamRole::VideoRecording);
|
|
||||||
}
|
|
||||||
|
|
||||||
config_ = camera_->generateConfiguration(roles);
|
|
||||||
if (!config_ || config_->size() != roles.size()) {
|
|
||||||
std::cerr << "Failed to get default stream configuration"
|
|
||||||
<< std::endl;
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Apply configuration if explicitly requested. */
|
|
||||||
if (options.isSet(OptStream)) {
|
|
||||||
const std::vector<OptionValue> &streamOptions =
|
|
||||||
options[OptStream].toArray();
|
|
||||||
|
|
||||||
unsigned int i = 0;
|
|
||||||
for (auto const &value : streamOptions) {
|
|
||||||
KeyValueParser::Options opt = value.toKeyValues();
|
|
||||||
StreamConfiguration &cfg = config_->at(i++);
|
|
||||||
|
|
||||||
if (opt.isSet("width"))
|
|
||||||
cfg.size.width = opt["width"];
|
|
||||||
|
|
||||||
if (opt.isSet("height"))
|
|
||||||
cfg.size.height = opt["height"];
|
|
||||||
|
|
||||||
/* TODO: Translate 4CC string to ID. */
|
|
||||||
if (opt.isSet("pixelformat"))
|
|
||||||
cfg.pixelFormat = opt["pixelformat"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
streamName_.clear();
|
|
||||||
for (unsigned int index = 0; index < config_->size(); ++index) {
|
|
||||||
StreamConfiguration &cfg = config_->at(index);
|
|
||||||
streamName_[cfg.stream()] = "stream" + std::to_string(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Capture::capture(EventLoop *loop)
|
int Capture::capture(EventLoop *loop)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
|
@ -20,19 +20,18 @@
|
||||||
class Capture
|
class Capture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Capture(libcamera::Camera *camera);
|
Capture(libcamera::Camera *camera,
|
||||||
|
libcamera::CameraConfiguration *config);
|
||||||
|
|
||||||
int run(EventLoop *loop, const OptionsParser::Options &options);
|
int run(EventLoop *loop, const OptionsParser::Options &options);
|
||||||
private:
|
private:
|
||||||
int prepareConfig(const OptionsParser::Options &options);
|
|
||||||
|
|
||||||
int capture(EventLoop *loop);
|
int capture(EventLoop *loop);
|
||||||
|
|
||||||
void requestComplete(libcamera::Request *request,
|
void requestComplete(libcamera::Request *request,
|
||||||
const std::map<libcamera::Stream *, libcamera::Buffer *> &buffers);
|
const std::map<libcamera::Stream *, libcamera::Buffer *> &buffers);
|
||||||
|
|
||||||
libcamera::Camera *camera_;
|
libcamera::Camera *camera_;
|
||||||
std::unique_ptr<libcamera::CameraConfiguration> config_;
|
libcamera::CameraConfiguration *config_;
|
||||||
|
|
||||||
std::map<libcamera::Stream *, std::string> streamName_;
|
std::map<libcamera::Stream *, std::string> streamName_;
|
||||||
BufferWriter *writer_;
|
BufferWriter *writer_;
|
||||||
|
|
|
@ -33,19 +33,21 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int parseOptions(int argc, char *argv[]);
|
int parseOptions(int argc, char *argv[]);
|
||||||
|
int prepareConfig();
|
||||||
int run();
|
int run();
|
||||||
|
|
||||||
static CamApp *app_;
|
static CamApp *app_;
|
||||||
OptionsParser::Options options_;
|
OptionsParser::Options options_;
|
||||||
CameraManager *cm_;
|
CameraManager *cm_;
|
||||||
std::shared_ptr<Camera> camera_;
|
std::shared_ptr<Camera> camera_;
|
||||||
|
std::unique_ptr<libcamera::CameraConfiguration> config_;
|
||||||
EventLoop *loop_;
|
EventLoop *loop_;
|
||||||
};
|
};
|
||||||
|
|
||||||
CamApp *CamApp::app_ = nullptr;
|
CamApp *CamApp::app_ = nullptr;
|
||||||
|
|
||||||
CamApp::CamApp()
|
CamApp::CamApp()
|
||||||
: cm_(nullptr), camera_(nullptr), loop_(nullptr)
|
: cm_(nullptr), camera_(nullptr), config_(nullptr), loop_(nullptr)
|
||||||
{
|
{
|
||||||
CamApp::app_ = this;
|
CamApp::app_ = this;
|
||||||
}
|
}
|
||||||
|
@ -97,6 +99,10 @@ int CamApp::init(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Using camera " << camera_->name() << std::endl;
|
std::cout << "Using camera " << camera_->name() << std::endl;
|
||||||
|
|
||||||
|
ret = prepareConfig();
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
loop_ = new EventLoop(cm_->eventDispatcher());
|
loop_ = new EventLoop(cm_->eventDispatcher());
|
||||||
|
@ -114,6 +120,8 @@ void CamApp::cleanup()
|
||||||
camera_.reset();
|
camera_.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config_.reset();
|
||||||
|
|
||||||
cm_->stop();
|
cm_->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,6 +183,69 @@ int CamApp::parseOptions(int argc, char *argv[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CamApp::prepareConfig()
|
||||||
|
{
|
||||||
|
StreamRoles roles;
|
||||||
|
|
||||||
|
if (options_.isSet(OptStream)) {
|
||||||
|
const std::vector<OptionValue> &streamOptions =
|
||||||
|
options_[OptStream].toArray();
|
||||||
|
|
||||||
|
/* Use roles and get a default configuration. */
|
||||||
|
for (auto const &value : streamOptions) {
|
||||||
|
KeyValueParser::Options opt = value.toKeyValues();
|
||||||
|
|
||||||
|
if (!opt.isSet("role")) {
|
||||||
|
roles.push_back(StreamRole::VideoRecording);
|
||||||
|
} else if (opt["role"].toString() == "viewfinder") {
|
||||||
|
roles.push_back(StreamRole::Viewfinder);
|
||||||
|
} else if (opt["role"].toString() == "video") {
|
||||||
|
roles.push_back(StreamRole::VideoRecording);
|
||||||
|
} else if (opt["role"].toString() == "still") {
|
||||||
|
roles.push_back(StreamRole::StillCapture);
|
||||||
|
} else {
|
||||||
|
std::cerr << "Unknown stream role "
|
||||||
|
<< opt["role"].toString() << std::endl;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* If no configuration is provided assume a single video stream. */
|
||||||
|
roles.push_back(StreamRole::VideoRecording);
|
||||||
|
}
|
||||||
|
|
||||||
|
config_ = camera_->generateConfiguration(roles);
|
||||||
|
if (!config_ || config_->size() != roles.size()) {
|
||||||
|
std::cerr << "Failed to get default stream configuration"
|
||||||
|
<< std::endl;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply configuration if explicitly requested. */
|
||||||
|
if (options_.isSet(OptStream)) {
|
||||||
|
const std::vector<OptionValue> &streamOptions =
|
||||||
|
options_[OptStream].toArray();
|
||||||
|
|
||||||
|
unsigned int i = 0;
|
||||||
|
for (auto const &value : streamOptions) {
|
||||||
|
KeyValueParser::Options opt = value.toKeyValues();
|
||||||
|
StreamConfiguration &cfg = config_->at(i++);
|
||||||
|
|
||||||
|
if (opt.isSet("width"))
|
||||||
|
cfg.size.width = opt["width"];
|
||||||
|
|
||||||
|
if (opt.isSet("height"))
|
||||||
|
cfg.size.height = opt["height"];
|
||||||
|
|
||||||
|
/* TODO: Translate 4CC string to ID. */
|
||||||
|
if (opt.isSet("pixelformat"))
|
||||||
|
cfg.pixelFormat = opt["pixelformat"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int CamApp::run()
|
int CamApp::run()
|
||||||
{
|
{
|
||||||
if (options_.isSet(OptList)) {
|
if (options_.isSet(OptList)) {
|
||||||
|
@ -188,7 +259,7 @@ int CamApp::run()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options_.isSet(OptCapture)) {
|
if (options_.isSet(OptCapture)) {
|
||||||
Capture capture(camera_.get());
|
Capture capture(camera_.get(), config_.get());
|
||||||
return capture.run(loop_, options_);
|
return capture.run(loop_, options_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue