summaryrefslogtreecommitdiff
AgeCommit message (Expand)Author
2019-04-29libcamera: device_enumerator_udev: Include missing headerLaurent Pinchart
2019-04-29libcamera: Don't ignore the return value of read() and write()Laurent Pinchart
2019-04-28Documentation: Drop install directive for DoxyfileNiklas Söderlund
2019-04-28libcamera: camera: Log proposed configuration in streamConfiguration()Laurent Pinchart
2019-04-28libcamera: camera: Check requests before queueing themNiklas Söderlund
2019-04-27test: signal: Exercise the signal delivery code paths for ObjectLaurent Pinchart
2019-04-27libcamera: Make libudev optionalLaurent Pinchart
2019-04-27libcamera: v4l2_device: Prefix V4L2 direction in log messagesKieran Bingham
2019-04-26libcamera: Remove outdated \todo commentsLaurent Pinchart
2019-04-26cam: options: Fix string concatenationLaurent Pinchart
2019-04-26cam: options: Don't initialise variable-length arraysLaurent Pinchart
2019-04-26test: v4l2_subdevice: Remove std::move() that prevents copy elisionLaurent Pinchart
2019-04-26libcamera: v4l2_device: Buffer is not a structLaurent Pinchart
2019-04-26libcamera: Mark overridden functions with overrideLaurent Pinchart
2019-04-26libcamera: log: Add a LogInvalid entry to LogSeverityLaurent Pinchart
2019-04-26libcamera: event_dispatcher_poll: Fix bitwise testLaurent Pinchart
2019-04-26libcamera: Correct struct forward declarationsLaurent Pinchart
2019-04-26libcamera: utils: call secure_getenv() if it exists or workaround with issetu...Giulio Benetti
2019-04-26meson: check if secure_getenv() is presentGiulio Benetti
2019-04-19libcamera: ipu3: Connect viewfinder's BufferReady signalJacopo Mondi
2019-04-19libcamera: ipu3: Queue requests for multiple streamsJacopo Mondi
2019-04-19libcamera: ipu3: Add multiple stream memory managementJacopo Mondi
2019-04-19libcamera: ipu3: Use roles in stream configurationJacopo Mondi
2019-04-19libcamera: ipu3: Create camera with 2 streamsJacopo Mondi
2019-04-19libcamera: camera: Reset basefield to decimalJacopo Mondi
2019-04-19libcamera: stream: Document protected membersJacopo Mondi
2019-04-19libcamera: Include header related to source file firstLaurent Pinchart
2019-04-19libcamera: stream: Add and use toString() method to StreamConfigurationLaurent Pinchart
2019-04-19libcamera: pipeline: rkisp1: Don't hardcode NV12 in configureStreams()Laurent Pinchart
2019-04-19libcamera: Document documentation style and update the code accordinglyLaurent Pinchart
2019-04-18libcamera: pipeline: Add RKISP1 pipelineLaurent Pinchart
2019-04-18libcamera: pipeline: ipu3: Use the new CameraSensor classLaurent Pinchart
2019-04-18libcamera: camera_sensor: Add a new class to model a camera sensorLaurent Pinchart
2019-04-18libcamera: v4l2_subdevice: Add method to retrieve the media entityLaurent Pinchart
2019-04-18libcamera: v4l2_subdevice: Close subdevice when destroyedLaurent Pinchart
2019-04-18libcamera: utils: Add set_overlap() functionLaurent Pinchart
2019-04-18test: geometry: Add tests for Size class comparison operatorsLaurent Pinchart
2019-04-18libcamera: geometry: Add comparison operators to geometry classesLaurent Pinchart
2019-04-18libcamera: geometry: Use Size to store min and max in SizeRangeLaurent Pinchart
2019-04-18libcamera: geometry: Sort classes alphabeticallyLaurent Pinchart
2019-04-18libcamera: camera: Log requested configuration in configureStreams()Laurent Pinchart
2019-04-18libcamera: log: Mark Loggable::_log() methods as constLaurent Pinchart
2019-04-18Install the cam and qcam utilitiesLaurent Pinchart
2019-04-18libcamera: buffer: Store Request reference in BufferJacopo Mondi
2019-04-18libcamera: request: Expose the Stream to Buffers mapJacopo Mondi
2019-04-18libcamera: camera: Validate Request before queueing itJacopo Mondi
2019-04-18libcamera: request: Add hasPendingBuffers() methodJacopo Mondi
2019-04-18libcamera: v4l2_device: Propagate releaseBuffers() errorJacopo Mondi
2019-04-18libcamera: camera: Don't call freeBuffer() on allocateBuffer() errorJacopo Mondi
2019-04-17libcamera: camera: Pass the stream set to allocate/freeBuffers()Jacopo Mondi
meraSensor::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 " << utils::hex(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 ControlInfoMap &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(ControlList *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(ControlList *ctrls) { return subdev_->setControls(ctrls); } std::string CameraSensor::logPrefix() const { return "'" + subdev_->entity()->name() + "'"; } } /* namespace libcamera */