summaryrefslogtreecommitdiff
path: root/Documentation/meson.build
AgeCommit message (Collapse)Author
2019-07-09libcamera: Rework automatic version generation to avoid rebuildsLaurent Pinchart
Commit b817bcec6b53 ("libcamera: Auto generate version information") generates version information in order to automatically include it various locations (Sphinx and Doxygen documentation, libcamera::version variable available at runtime, and version.h available at compile time). Unfortunately this causes lots of unnecessary rebuilds when modifying the git tree state, which hinders development. The problem is caused by the generated version.h being listed as a dependency for the whole libcamera. This is required as meson (to the best of my knowledge) doesn't provide a way to explicitly specify the dependency of a single object file (camera_manager.o in this case, as camera_manager.cpp is the only consumer of the generated version string) on the custom target used to generate version.h. The dependency can't be automatically detected at build time, like dependencies on normal headers that are generated by parsing the source, because the version.h header may not exist yet. The build could then fail in a racy way. This change attempts at solving the issue by generating a version.cpp instead of a version.h to set the git-based version. This minimises the number of files that need to be rebuild when then git tree state changes, while retaining the main purpose of the original automatic version generation, the ability to access the git-based version string at runtime. We however lose the ability to access git-based version information at build time in an application building against libcamera, but there is no expected use case for this. The version string is moved from the libcamera namespace to the CameraManager class in order to avoid including version.h inside libcamera (in version.cpp and in camera_manager.cpp), which would create dependencies causing more rebuild steps, as described above. On the other hand, major, minor and patch level version numbers are useful at build time. This commit changes the generation of version.h in order to add three macros named LIBCAMERA_VERSION_MAJOR, LIBCAMERA_VERSION_MINOR and LIBCAMERA_VERSION_PATCH for this purpose. version.h is not included by any other libcamera header or source file, and thus doesn't force a rebuild of the library. The Sphinx and Doxygen documentation keep their git-based version information, which is set during the configuration of the build and then doesn't track git commits. We may want to investigate how to improve this, but given that git-based version for the documentation has very few use cases outside of tagging nightly builds, this isn't considered an issue at the moment. The documentation install directory now uses the base version string, in order to avoid increasing the number of documentation directories needlessly. This shouldn't cause any issue as the API should not change without a change to the version number. The version number generation and handling code now also standardises the version variables to not start with a 'v' prefix in meson, in order to simplify their handling. The prefix is added when generating the relevant files. Note that we go back to specifying the fallback version in the main meson.build, in the call to the project() function. For the time being I believe this should be a good compromise to avoid unnecessary recompilation, and moving the fallback version to a different file for tarball releases can be built on top of this. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-07-04Documentation: Wrap extended doc_install_dir lineKieran Bingham
The doc_install_dir is longer than 80 chars. Wrap it accordingly. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-07-04libcamera: Auto generate version informationKieran Bingham
Generate a version string, and provide a global string object which allows applications to interrogate the current libcamera version information. The version header is automatically updated by meson on each build. The string roughly follows the semver [0] conventions of major.minor.patch-label as a value. [0] https://semver.org/ A script (utils/gen-version.sh) is provided which is modelled upon the processing from autoconf's git-version-gen. The gen-version.sh script will look for tags in the form vX.Y as starting points for the version string. While the repository does not have any matching tags, v0.0 will be assumed, resulting in versions with both major and minor being set to '0', and the patch count resulting from the number of patches in the history to that point. Finally, a uniquely identifying shortened hash is provided from git: v0.0.509+0ec0edf7 Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-05-23meson: Fix coding style in meson.build filesLaurent Pinchart
Consistently go for 4 spaces indentation, and always put a space between the colon in argument lists, as per the examples from the meson documentation. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-04-28Documentation: Drop install directive for DoxyfileNiklas Söderlund
Building the documentation reports warnings, WARNING: Project targetting '>= 0.40' but tried to use feature introduced in '0.50.0': install arg in configure_file WARNING: Project specifies a minimum meson_version '>= 0.40' but uses features which were added in newer versions: * 0.50.0: {'install arg in configure_file'} Due to the usage of the directive configure_file { install: false } in Documentation/meason.build which is introduced in meson 0.50. As we do not wish to install the Doxyfile no install_dir is set so there is no need to explicitly state that it should not be installed. Silence the warning by dropping the install directive. Fixes: 53c4d4c34fc49b95 ("Documentation: Generate source code documentation using Doxygen") Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-01-14Documentation: quieten sphinx-build outputKieran Bingham
The output of the sphinx-build for our documentation is overly verbose. Reduce this output to warnings and errors with the '-q' quiet option. Acked-by: Jacopo Mondi <jacopo@jmondi.org> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2018-12-14Documentation: Add architecture documentationLaurent Pinchart
The documentation is copied mostly verbatim from the website, with small modifications to the ascii art diagrams to make them compile. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Jacopo Mondi <jacopo@jmondi.org> Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2018-12-13Documentation: Add coding style documentJacopo Mondi
Add document to summarize the coding style adopted by libcamera. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2018-12-12Documentation: Generate source code documentation using DoxygenLaurent Pinchart
Extend the documentation build system to automatically generate documentation from source code using Doxygen. This is currently separate from the sphinx documentation, and should be integrated using the breathe (and possibly exhale) extensions. As the Documentation/meson.build file needs to reference the variables holding the source files, move the Documentation directory to the end of the subdirs() in the top-level meson.build. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2018-12-12Documentation: Don't hardcode install directoryLaurent Pinchart
Use the datadir option to select the directory in which to install documentation. This defaults to $prefix/share so this doesn't introduce any change in the default case. While at it use join_paths() to join patch components instead of hardcoding the / separator. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2018-12-11Documentation: Set install_dir in custom_target()Laurent Pinchart
The custom_target() function accepts an install_dir parameter. Along with setting install to true, this can be used to replace the install_subdir() function. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2018-11-28Documentation: Introduce sphinx documentationKieran Bingham
Utilise sphinx-build to generate documentation in HTML form, and populate with some initial content. An initial conf.py is generated from sphinx-quickstart and answering initial questions. Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
com"> * Once constructed the instance must be initialized with init(). */ CameraSensor::CameraSensor(const MediaEntity *entity) : entity_(entity) { subdev_ = new V4L2Subdevice(entity); } /** * \brief Destroy a CameraSensor */ CameraSensor::~CameraSensor() { delete subdev_; } /** * \brief Initialize the camera sensor instance * * This method performs the initialisation steps of the CameraSensor that may * fail. It shall be called once and only once after constructing the instance. * * \return 0 on success or a negative error code otherwise */ int CameraSensor::init() { int ret; if (entity_->pads().size() != 1) { LOG(CameraSensor, Error) << "Sensors with more than one pad are not supported"; return -EINVAL; } if (entity_->function() != MEDIA_ENT_F_CAM_SENSOR) { LOG(CameraSensor, Error) << "Invalid sensor function 0x" << std::hex << std::setfill('0') << std::setw(8) << entity_->function(); return -EINVAL; } ret = subdev_->open(); if (ret < 0) return ret; /* Enumerate and cache media bus codes and sizes. */ const ImageFormats formats = subdev_->formats(0); if (formats.isEmpty()) { LOG(CameraSensor, Error) << "No image format found"; return -EINVAL; } mbusCodes_ = formats.formats(); /* * Extract the supported sizes from the first format as we only support * sensors that offer the same frame sizes for all media bus codes. * Verify this assumption and reject the sensor if it isn't true. */ const std::vector<SizeRange> &sizes = formats.sizes(mbusCodes_[0]); std::transform(sizes.begin(), sizes.end(), std::back_inserter(sizes_), [](const SizeRange &range) { return range.max; }); for (unsigned int code : mbusCodes_) { if (formats.sizes(code) != sizes) { LOG(CameraSensor, Error) << "Frame sizes differ between media bus codes"; return -EINVAL; } } /* Sort the media bus codes and sizes. */ std::sort(mbusCodes_.begin(), mbusCodes_.end()); std::sort(sizes_.begin(), sizes_.end()); return 0; } /** * \fn CameraSensor::entity() * \brief Retrieve the sensor media entity * \return The sensor media entity */ /** * \fn CameraSensor::mbusCodes() * \brief Retrieve the media bus codes supported by the camera sensor * \return The supported media bus codes sorted in increasing order */ /** * \fn CameraSensor::sizes() * \brief Retrieve the frame sizes supported by the camera sensor * \return The supported frame sizes sorted in increasing order */ /** * \brief Retrieve the camera sensor resolution * \return The camera sensor resolution in pixels */ const Size &CameraSensor::resolution() const { /* * The sizes_ vector is sorted in ascending order, the resolution is * thus the last element of the vector. */ return sizes_.back(); } /** * \brief Retrieve the best sensor format for a desired output * \param[in] mbusCodes The list of acceptable media bus codes * \param[in] size The desired size * * Media bus codes are selected from \a mbusCodes, which lists all acceptable * codes in decreasing order of preference. This method selects the first code * from the list that is supported by the sensor. If none of the desired codes * is supported, it returns an error. * * \a size indicates the desired size at the output of the sensor. This method * selects the best size supported by the sensor according to the following * criteria. * * - The desired \a size shall fit in the sensor output size to avoid the need * to up-scale. * - The sensor output size shall match the desired aspect ratio to avoid the * need to crop the field of view. * - The sensor output size shall be as small as possible to lower the required * bandwidth. * * The use of this method is optional, as the above criteria may not match the * needs of all pipeline handlers. Pipeline handlers may implement custom * sensor format selection when needed. * * The returned sensor output format is guaranteed to be acceptable by the * setFormat() method without any modification. * * \return The best sensor output format matching the desired media bus codes * and size on success, or an empty format otherwise. */ V4L2SubdeviceFormat CameraSensor::getFormat(const std::vector<unsigned int> &mbusCodes, const Size &size) const { V4L2SubdeviceFormat format{}; for (unsigned int code : mbusCodes) { if (std::any_of(mbusCodes_.begin(), mbusCodes_.end(), [code](unsigned int c) { return c == code; })) { format.mbus_code = code; break; } } if (!format.mbus_code) { LOG(CameraSensor, Debug) << "No supported format found"; return format; } unsigned int desiredArea = size.width * size.height; unsigned int bestArea = UINT_MAX; float desiredRatio = static_cast<float>(size.width) / size.height; float bestRatio = FLT_MAX; const Size *bestSize = nullptr; for (const Size &sz : sizes_) { if (sz.width < size.width || sz.height < size.height) continue; float ratio = static_cast<float>(sz.width) / sz.height; float ratioDiff = fabsf(ratio - desiredRatio); unsigned int area = sz.width * sz.height; unsigned int areaDiff = area - desiredArea; if (ratioDiff > bestRatio) continue; if (ratioDiff < bestRatio || areaDiff < bestArea) { bestRatio = ratioDiff; bestArea = areaDiff; bestSize = &sz; } } if (!bestSize) { LOG(CameraSensor, Debug) << "No supported size found"; return format; } format.size = *bestSize; return format; } /** * \brief Set the sensor output format * \param[in] format The desired sensor output format * \return 0 on success or a negative error code otherwise */ int CameraSensor::setFormat(V4L2SubdeviceFormat *format) { return subdev_->setFormat(0, format); } /** * \brief Retrieve the supported V4L2 controls and their information * \return A map of the V4L2 controls supported by the sensor */ const V4L2ControlInfoMap &CameraSensor::controls() const { return subdev_->controls(); } /** * \brief Read controls from the sensor * \param[inout] ctrls The list of controls to read * * This method reads the value of all controls contained in \a ctrls, and stores * their values in the corresponding \a ctrls entry. * * If any control in \a ctrls is not supported by the device, is disabled (i.e. * has the V4L2_CTRL_FLAG_DISABLED flag set), is a compound control, or if any * other error occurs during validation of the requested controls, no control is * read and this method returns -EINVAL. * * If an error occurs while reading the controls, the index of the first control * that couldn't be read is returned. The value of all controls below that index * are updated in \a ctrls, while the value of all the other controls are not * changed. * * \sa V4L2Device::getControls() * * \return 0 on success or an error code otherwise * \retval -EINVAL One of the control is not supported or not accessible * \retval i The index of the control that failed */ int CameraSensor::getControls(V4L2ControlList *ctrls) { return subdev_->getControls(ctrls); } /** * \brief Write controls to the sensor * \param[in] ctrls The list of controls to write * * This method writes the value of all controls contained in \a ctrls, and * stores the values actually applied to the device in the corresponding * \a ctrls entry. * * If any control in \a ctrls is not supported by the device, is disabled (i.e. * has the V4L2_CTRL_FLAG_DISABLED flag set), is read-only, is a * compound control, or if any other error occurs during validation of * the requested controls, no control is written and this method returns * -EINVAL. * * If an error occurs while writing the controls, the index of the first * control that couldn't be written is returned. All controls below that index * are written and their values are updated in \a ctrls, while all other * controls are not written and their values are not changed. * * \sa V4L2Device::setControls() * * \return 0 on success or an error code otherwise * \retval -EINVAL One of the control is not supported or not accessible * \retval i The index of the control that failed */ int CameraSensor::setControls(V4L2ControlList *ctrls) { return subdev_->setControls(ctrls); } std::string CameraSensor::logPrefix() const { return "'" + subdev_->entity()->name() + "'"; } } /* namespace libcamera */