summaryrefslogtreecommitdiff
path: root/src/apps/cam/camera_session.cpp
AgeCommit message (Collapse)Author
2024-10-21apps: cam: Print control vendor information when listing controlsPaul Elder
Now that the vendor of the control can be queried, print it in --list-controls. Example output: $ cam -c 1 --list-controls Using camera platform/vimc.0 Sensor B as cam0 Control: libcamera::Brightness: [-1.000000..1.000000] Control: libcamera::Contrast: [0.000000..2.000000] Control: libcamera::Saturation: [0.000000..2.000000] Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-30apps: cam: Print an error when outputting DNG and DNG support is missingLaurent Pinchart
When DNG support is missing, the cam application ignores the .dng suffix of the file pattern and writes raw binary data instead, without notifying the user. This leads to confusion. Fix it by printing an error message. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Milan Zamazal <mzamazal@redhat.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-09-25apps: cam: Print control array sizesPaul Elder
Now that controls can be queried for array information, print it in --list-controls when applicable. Example output (with dummy controls added to vimc): $ cam -c 1 --list-controls Using camera platform/vimc.0 Sensor B as cam0 Control: ColourGains: [1.000000..4.000000] Size: 2 Control: Brightness: [-1.000000..1.000000] Control: AfWindows: [(0, 0)/1x1..(0, 0)/100x100] Size: n Control: Contrast: [0.000000..2.000000] Control: Saturation: [0.000000..2.000000] Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-25apps: cam: Print control enum values more nicelyPaul Elder
Now that enum names can be obtained from ControlId, use that information to print out the list of supported enum values in --list-controls. Example output (with a dummy AwbMode ControlInfo added to vimc): $ cam -c 1 --list-controls Using camera platform/vimc.0 Sensor B as cam0 Control: AwbMode: - AwbTungsten (2) - AwbFluorescent (3) - AwbDaylight (5) Control: Brightness: [-1.000000..1.000000] Control: Contrast: [0.000000..2.000000] Control: Saturation: [0.000000..2.000000] Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-05-21treewide: Query list of cameras just onceBarnabás Pőcze
This is more efficient since only a single vector will be constructed, and furthermore, it prevents the TOCTOU issue that might arise when the list of cameras changes between the two queries. Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com> 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>
2024-05-08libcamera: Drop file name from header comment blocksLaurent Pinchart
Source files in libcamera start by a comment block header, which includes the file name and a one-line description of the file contents. While the latter is useful to get a quick overview of the file contents at a glance, the former is mostly a source of inconvenience. The name in the comments can easily get out of sync with the file name when files are renamed, and copy & paste during development have often lead to incorrect names being used to start with. Readers of the source code are expected to know which file they're looking it. Drop the file name from the header comment block. The change was generated with the following script: ---------------------------------------- dirs="include/libcamera src test utils" declare -rA patterns=( ['c']=' \* ' ['cpp']=' \* ' ['h']=' \* ' ['py']='# ' ['sh']='# ' ) for ext in ${!patterns[@]} ; do files=$(for dir in $dirs ; do find $dir -name "*.${ext}" ; done) pattern=${patterns[${ext}]} for file in $files ; do name=$(basename ${file}) sed -i "s/^\(${pattern}\)${name} - /\1/" "$file" done done ---------------------------------------- This misses several files that are out of sync with the comment block header. Those will be addressed separately and manually. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-05-03apps: cam: Fix C++20 deprecation warningBarnabás Pőcze
C++20 deprecated implicit capture of `this` via `[=]`. Fix that by explicitly capturing the necessary variables. Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-10-23apps: cam: Add option to set stream orientationJacopo Mondi
Add a '--orientation|-o' option to the cam test application to set an orientation to the image stream. Supported values are the ones obtained by applying flips to the camera sensor: - rot0: no rotation - rot180: rotate 180 degrees - flip: vertical flip - mirror: horizontal flip Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Reviewed-by: David Plowman <david.plowman@raspberrypi.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-07-04libcamera: Remove `StreamRoles` aliasBarnabás Pőcze
Now that `Camera::generateConfiguration()` takes a `libcamera::Span` of `StreamRole`, remove the `StreamRoles` type, which was an alias to `std::vector<libcamera::StreamRole>`. The removal has two reasons: - it is no longer strictly necessary, - its presence may suggest that that is the preferred (or correct) way to build/pass a list of `StreamRole`. Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> [Kieran: Fix small checkstyle report on roles initialiser] Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2022-10-24apps: Share common source between applicationsLaurent Pinchart
Multiple source files in the src/apps/cam/ directory are used by cam, qcam and lc-compliance. They are compiled separately for each application. Move them to a new src/apps/common/ directory and compile them in a static library to decrease the number of compilation operations. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2022-10-20Move test applications to src/apps/Laurent Pinchart
The cam and qcam test application share code, currently through a crude hack that references the cam source files directly from the qcam meson.build file. To prepare for the introduction of hosting that code in a static library, move all applications to src/apps/. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
sing namespace libcamera; using namespace std::literals::chrono_literals; class UtilsTest : public Test { protected: int testDirname() { static const std::vector<std::string> paths = { "", "///", "/bin", "/usr/bin", "//etc////", "//tmp//d//", "current_file", "./current_file", "./current_dir/", "current_dir/", }; static const std::vector<std::string> expected = { ".", "/", "/", "/usr", "/", "//tmp", ".", ".", ".", ".", }; std::vector<std::string> results; for (const auto &path : paths) results.push_back(utils::dirname(path)); if (results != expected) { cerr << "utils::dirname() tests failed" << endl; cerr << "expected: " << endl; for (const auto &path : expected) cerr << "\t" << path << endl; cerr << "results: " << endl; for (const auto &path : results) cerr << "\t" << path << endl; return TestFail; } return TestPass; } int testEnumerate() { std::vector<unsigned int> integers{ 1, 2, 3, 4, 5 }; unsigned int i = 0; for (auto [index, value] : utils::enumerate(integers)) { if (index != i || value != i + 1) { cerr << "utils::enumerate(<vector>) test failed: i=" << i << ", index=" << index << ", value=" << value << std::endl; return TestFail; } /* Verify that we can modify the value. */ --value; ++i; } if (integers != std::vector<unsigned int>{ 0, 1, 2, 3, 4 }) { cerr << "Failed to modify container in enumerated range loop" << endl; return TestFail; } Span<const unsigned int> span{ integers }; i = 0; for (auto [index, value] : utils::enumerate(span)) { if (index != i || value != i) { cerr << "utils::enumerate(<span>) test failed: i=" << i << ", index=" << index << ", value=" << value << std::endl; return TestFail; } ++i; } const unsigned int array[] = { 0, 2, 4, 6, 8 }; i = 0; for (auto [index, value] : utils::enumerate(array)) { if (index != i || value != i * 2) { cerr << "utils::enumerate(<array>) test failed: i=" << i << ", index=" << index << ", value=" << value << std::endl; return TestFail; } ++i; } return TestPass; } int testDuration() { std::ostringstream os; utils::Duration exposure; double ratio; exposure = 25ms + 25ms; if (exposure.get<std::micro>() != 50000.0) { cerr << "utils::Duration failed to return microsecond count"; return TestFail; } exposure = 1.0s / 4; if (exposure != 250ms) { cerr << "utils::Duration failed scalar divide test"; return TestFail; } exposure = 5000.5us; if (!exposure) { cerr << "utils::Duration failed boolean test"; return TestFail; } os << exposure; if (os.str() != "5000.50us") { cerr << "utils::Duration operator << failed"; return TestFail; } exposure = 100ms; ratio = exposure / 25ms; if (ratio != 4.0) { cerr << "utils::Duration failed ratio test"; return TestFail; } return TestPass; } int run() { /* utils::hex() test. */ std::ostringstream os; std::string ref; os << utils::hex(static_cast<int32_t>(0x42)) << " "; ref += "0x00000042 "; os << utils::hex(static_cast<uint32_t>(0x42)) << " "; ref += "0x00000042 "; os << utils::hex(static_cast<int64_t>(0x42)) << " "; ref += "0x0000000000000042 "; os << utils::hex(static_cast<uint64_t>(0x42)) << " "; ref += "0x0000000000000042 "; os << utils::hex(static_cast<int32_t>(0x42), 4) << " "; ref += "0x0042 "; os << utils::hex(static_cast<uint32_t>(0x42), 1) << " "; ref += "0x42 "; os << utils::hex(static_cast<int64_t>(0x42), 4) << " "; ref += "0x0042 "; os << utils::hex(static_cast<uint64_t>(0x42), 1) << " "; ref += "0x42 "; std::string s = os.str(); if (s != ref) { cerr << "utils::hex() test failed, expected '" << ref << "', got '" << s << "'"; return TestFail; } /* utils::join() and utils::split() test. */ std::vector<std::string> elements = { "/bin", "/usr/bin", "", "", }; std::string path; for (const auto &element : elements) path += (path.empty() ? "" : ":") + element; if (path != utils::join(elements, ":")) { cerr << "utils::join() test failed" << endl; return TestFail; } std::vector<std::string> dirs; for (const auto &dir : utils::split(path, ":")) dirs.push_back(dir); if (dirs != elements) { cerr << "utils::split() test failed" << endl; return TestFail; } /* utils::join() with conversion function test. */ std::vector<Size> sizes = { { 0, 0 }, { 100, 100 } }; s = utils::join(sizes, "/", [](const Size &size) { return size.toString(); }); if (s != "0x0/100x100") { cerr << "utils::join() with conversion test failed" << endl; return TestFail; } /* utils::dirname() tests. */ if (TestPass != testDirname()) return TestFail; /* utils::map_keys() test. */ const std::map<std::string, unsigned int> map{ { "zero", 0 }, { "one", 1 }, { "two", 2 }, }; std::vector<std::string> expectedKeys{ "zero", "one", "two", }; std::sort(expectedKeys.begin(), expectedKeys.end()); const std::vector<std::string> keys = utils::map_keys(map); if (keys != expectedKeys) { cerr << "utils::map_keys() test failed" << endl; return TestFail; } /* utils::alignUp() and utils::alignDown() tests. */ if (utils::alignDown(6, 3) != 6 || utils::alignDown(7, 3) != 6) { cerr << "utils::alignDown test failed" << endl; return TestFail; } if (utils::alignUp(6, 3) != 6 || utils::alignUp(7, 3) != 9) { cerr << "utils::alignUp test failed" << endl; return TestFail; } /* utils::enumerate() test. */ if (testEnumerate() != TestPass) return TestFail; /* utils::Duration test. */ if (testDuration() != TestPass) return TestFail; return TestPass; } }; TEST_REGISTER(UtilsTest)