[libcamera-devel] [PATCH 6/6] cam: add --format option to configure a stream
Niklas Söderlund
niklas.soderlund at ragnatech.se
Mon Jan 28 01:41:09 CET 2019
Add a option to configure the first stream of a camera from an argument
with options and parse the width, height and pixel format from that
list.
The pixel format is still specified as a integer which should correspond
to the kernels FOURCC identifiers. Going forward this should be turned
into a string representation and the cam parser should translate between
the two.
Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
---
src/cam/main.cpp | 104 +++++++++++++++++++++++++++++++++++++++++------
1 file changed, 92 insertions(+), 12 deletions(-)
diff --git a/src/cam/main.cpp b/src/cam/main.cpp
index bde47a8f17983912..4b4ce9aa29c80bd1 100644
--- a/src/cam/main.cpp
+++ b/src/cam/main.cpp
@@ -20,7 +20,8 @@ using namespace libcamera;
OptionsParser::Options options;
enum {
- OptCamera = 'c',
+ OptCamera = 'C',
+ OptFormat = 'f',
OptHelp = 'h',
OptList = 'l',
};
@@ -35,10 +36,20 @@ void signalHandler(int signal)
static int parseOptions(int argc, char *argv[])
{
+ KeyValueParser formatKeyValue;
+ formatKeyValue.addOption("width", "Set width in pixels",
+ ArgumentRequired, "w");
+ formatKeyValue.addOption("height", "Set height in pixels",
+ ArgumentRequired, "h");
+ formatKeyValue.addOption("pixelformat", "Set pixel format",
+ ArgumentRequired, "pf");
+
OptionsParser parser;
parser.addOption(OptCamera, "Specify which camera to operate on",
"camera", ArgumentRequired, "camera");
+ parser.addOption(OptFormat, "Set format of the cameras first stream",
+ formatKeyValue, "format");
parser.addOption(OptHelp, "Display this help message", "help");
parser.addOption(OptList, "List all cameras", "list");
@@ -54,6 +65,42 @@ static int parseOptions(int argc, char *argv[])
return 0;
}
+int str2uint(std::string str, unsigned int *dest)
+{
+ if (!dest || str == "" || !sscanf(str.c_str(), "%d", dest))
+ return -EINVAL;
+ return 0;
+}
+
+bool configureStreams(Camera *camera, std::vector<Stream> &streams)
+{
+ if (!options.isKeyValue(OptFormat))
+ return false;
+
+ KeyValueParser::Options format = options.keyValues(OptFormat);
+
+ std::map<unsigned int, StreamConfiguration> config = camera->streamConfiguration(streams);
+ unsigned int id = streams.front().id();
+
+ if (format.isSet("width"))
+ if (str2uint(format["width"], &config[id].width))
+ return false;
+
+ if (format.isSet("height"))
+ if (str2uint(format["height"], &config[id].height))
+ return false;
+
+ /* TODO: Translate 4CC string to ID. */
+ if (format.isSet("pixelformat"))
+ if (str2uint(format["pixelformat"], &config[id].pixelFormat))
+ return false;
+
+ if (camera->configureStreams(config))
+ return false;
+
+ return true;
+}
+
int main(int argc, char **argv)
{
int ret;
@@ -63,6 +110,8 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
CameraManager *cm = CameraManager::instance();
+ std::shared_ptr<Camera> camera;
+ std::vector<Stream> streams;
ret = cm->start();
if (ret) {
@@ -71,31 +120,62 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
+ loop = new EventLoop(cm->eventDispatcher());
+
+ struct sigaction sa = {};
+ sa.sa_handler = &signalHandler;
+ sigaction(SIGINT, &sa, nullptr);
+
if (options.isSet(OptList)) {
std::cout << "Available cameras:" << std::endl;
- for (const std::shared_ptr<Camera> &camera : cm->cameras())
- std::cout << "- " << camera->name() << std::endl;
+ for (const std::shared_ptr<Camera> &cam : cm->cameras())
+ std::cout << "- " << cam->name() << std::endl;
}
if (options.isSet(OptCamera)) {
- std::shared_ptr<Camera> cam = cm->get(options[OptCamera]);
-
- if (cam) {
- std::cout << "Using camera " << cam->name() << std::endl;
- } else {
+ camera = cm->get(options[OptCamera]);
+ if (!camera) {
std::cout << "Camera " << options[OptCamera]
<< " not found" << std::endl;
+ goto out;
+ }
+
+ streams = camera->streams();
+ if (streams.size() != 1) {
+ std::cout << "Camera have " << streams.size()
+ << " streams, I only know how to work with 1"
+ << std::endl;
+ goto out;
+ }
+
+ if (camera->acquire()) {
+ std::cout << "Failed to acquire camera" << std::endl;
+ goto out;
}
+
+ std::cout << "Using camera " << camera->name() << std::endl;
}
- loop = new EventLoop(cm->eventDispatcher());
+ if (options.isSet(OptFormat)) {
+ if (!camera) {
+ std::cout << "Can't configure stream, no camera selected" << std::endl;
+ goto out_camera;
+ }
- struct sigaction sa = {};
- sa.sa_handler = &signalHandler;
- sigaction(SIGINT, &sa, nullptr);
+ if (!configureStreams(camera.get(), streams)) {
+ std::cout << "Failed to configure camera" << std::endl;
+ goto out_camera;
+ }
+ }
ret = loop->exec();
+out_camera:
+ if (camera) {
+ camera->release();
+ camera.reset();
+ }
+out:
delete loop;
cm->stop();
--
2.20.1
More information about the libcamera-devel
mailing list