summaryrefslogtreecommitdiff
path: root/src/ipa/ipu3
AgeCommit message (Expand)Author
2022-09-28ipa: ipu3: Pass controls to algorithm's queueRequest() handlerLaurent Pinchart
2022-09-28ipa: ipu3: Use the FCQueueLaurent Pinchart
2022-09-28ipa: ipu3: Use base FrameContext classLaurent Pinchart
2022-09-28ipa: libipa: algorithm: process(): Pass frame numberKieran Bingham
2022-09-28ipa: libipa: algorithm: prepare(): Pass frame and frame ContextKieran Bingham
2022-09-27ipa: libipa: Pass a reference instead of pointer to Algorithm::process()Laurent Pinchart
2022-09-27ipa: ipu3: af: Pass context reference to afIsOutOfFocus()Laurent Pinchart
2022-09-27ipa: ipu3: Fix style of Doxygen comment blocksLaurent Pinchart
2022-08-30ipa: ipu3: Remove redundant call of std::string::c_str()Marvin Schmidt
2022-08-09ipa: ipu3: Add YAML tuning file supportLaurent Pinchart
2022-08-09ipa: ipu3: Register algorithmsLaurent Pinchart
2022-08-09ipa: ipu3: Add an uncalibrated.yaml tuning data fileLaurent Pinchart
2022-07-20libcamera: Remove extra ':' after '\todo'Laurent Pinchart
2022-06-29ipa: libipa: Introduce a Module class templateLaurent Pinchart
2022-06-18ipa: ipu3: awb: Correct the gains calculationJean-Michel Hautbois
2022-05-18ipa: ipu3: Put IPAFrameContext(s) in a ring bufferUmang Jain
2022-05-18ipa: libipa: Add frame context pointer in process()Umang Jain
2022-05-18ipa: ipu3: Rework IPAFrameContextUmang Jain
2022-04-14ipa: ipu3: af: A not initialized frame ignore counter fixingKate Hsuan
2022-04-09ipa: ipu3: af: Simplify accumulations of y_itemsKieran Bingham
2022-04-09ipa: ipu3: af: Use Span for y_table_item_tKieran Bingham
2022-04-09ipa: ipu3: af: Remove redundant memcpyKieran Bingham
2022-04-09ipa: ipu3: af: Use geometry classes to perform grid centeringKieran Bingham
2022-04-09ipa: ipu3: af: Move constants to implementationKieran Bingham
2022-04-09ipa: ipu3: af: enforce grid size restrictionsKieran Bingham
2022-04-08ipa: ipu3: Inline parseStatistics() into processStatsBuffer()Umang Jain
2022-04-08ipa: ipu3: Inline fillParams() in fillParamsBuffer()Umang Jain
2022-04-08ipa: ipu3: Replace event-based ops with dedicated functionsUmang Jain
2022-03-28ipa: ipu3: Ensure controls exists in before they are queriedUmang Jain
2022-03-28ipa: ipu3: Drop sensor controls private members from IPAIPU3Umang Jain
2022-03-28ipa: ipu3: Consolidate querying of exposure and gain limitsUmang Jain
2022-03-17ipa: ipu3: agc: Use existing local short-hand variable in configure()Laurent Pinchart
2022-03-17ipa: ipu3: agc: Reset frame count when configuring AGCLaurent Pinchart
2022-03-15ipa: ipu3: Send lens controls to pipeline handlerDaniel Scally
2022-03-15libcamera: ipa: Rename ctrls_ memberDaniel Scally
2022-03-15libcamera: ipa: Add lens control member to ipu3 ipa interfaceDaniel Scally
2022-03-15ipa: ipu3: af: Auto focus for dw9719 Surface Go2 VCMKate Hsuan
2022-03-11ipa: ipu3: awb: Clamp gain valuesJean-Michel Hautbois
2022-03-11ipa: ipu3: agc: Introduce lineDuration in IPASessionConfigurationJean-Michel Hautbois
2022-03-11ipa: ipu3: Shorten exposure and gain linesJean-Michel Hautbois
2022-03-11ipa: ipu3: Return filtered valueJean-Michel Hautbois
2021-12-07libcamera: Use utils::abs_diff()Laurent Pinchart
2021-11-30ipa: ipu3: Rectify gain value reporting in request metadataUmang Jain
2021-11-29ipa: libipa: Introduce Algorithm class templateJean-Michel Hautbois
2021-11-29ipa: Do not modify the sensor limitsJean-Michel Hautbois
2021-11-24ipa: ipu3: Convert to pragma onceKieran Bingham
2021-11-23ipa: ipu3: Fix IPAContext documentationJean-Michel Hautbois
2021-11-23ipa: ipu3: agc: Saturate the averages when computing relative luminanceLaurent Pinchart
2021-11-23ipa: ipu3: agc: Return the inter-quantile mean from measureBrightness()Laurent Pinchart
2021-11-23ipa: ipu3: agc: Rename currentYGainLaurent Pinchart
*/ int IPCUnixSocket::create() { int sockets[2]; int ret; ret = socketpair(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0, sockets); if (ret) { ret = -errno; LOG(IPCUnixSocket, Error) << "Failed to create socket pair: " << strerror(-ret); return ret; } ret = bind(sockets[0]); if (ret) return ret; return sockets[1]; } /** * \brief Bind to an existing IPC channel * \param[in] fd File descriptor * * This method binds the socket instance to an existing IPC channel identified * by the file descriptor \a fd. The file descriptor is obtained from the * IPCUnixSocket::create() method. * * \return 0 on success or a negative error code otherwise */ int IPCUnixSocket::bind(int fd) { if (isBound()) return -EINVAL; fd_ = fd; notifier_ = new EventNotifier(fd_, EventNotifier::Read); notifier_->activated.connect(this, &IPCUnixSocket::dataNotifier); return 0; } /** * \brief Close the IPC channel * * No communication is possible after close() has been called. */ void IPCUnixSocket::close() { if (!isBound()) return; delete notifier_; notifier_ = nullptr; ::close(fd_); fd_ = -1; headerReceived_ = false; } /** * \brief Check if the IPC channel is bound * \return True if the IPC channel is bound, false otherwise */ bool IPCUnixSocket::isBound() const { return fd_ != -1; } /** * \brief Send a message payload * \param[in] payload Message payload to send * * This method queues the message payload for transmission to the other end of * the IPC channel. It returns immediately, before the message is delivered to * the remote side. * * \return 0 on success or a negative error code otherwise */ int IPCUnixSocket::send(const Payload &payload) { int ret; if (!isBound()) return -ENOTCONN; Header hdr; hdr.data = payload.data.size(); hdr.fds = payload.fds.size(); if (!hdr.data && !hdr.fds) return -EINVAL; ret = ::send(fd_, &hdr, sizeof(hdr), 0); if (ret < 0) { ret = -errno; LOG(IPCUnixSocket, Error) << "Failed to send: " << strerror(-ret); return ret; } return sendData(payload.data.data(), hdr.data, payload.fds.data(), hdr.fds); } /** * \brief Receive a message payload * \param[out] payload Payload where to write the received message * * This method receives the message payload from the IPC channel and writes it * to the \a payload. If no message payload is available, it returns * immediately with -EAGAIN. The \ref readyRead signal shall be used to receive * notification of message availability. * * \todo Add state machine to make sure we don't block forever and that * a header is always followed by a payload. * * \return 0 on success or a negative error code otherwise * \retval -EAGAIN No message payload is available * \retval -ENOTCONN The socket is not connected (neither create() nor bind() * has been called) */ int IPCUnixSocket::receive(Payload *payload) { if (!isBound()) return -ENOTCONN; if (!headerReceived_) return -EAGAIN; payload->data.resize(header_.data); payload->fds.resize(header_.fds); int ret = recvData(payload->data.data(), header_.data, payload->fds.data(), header_.fds); if (ret < 0) return ret; headerReceived_ = false; notifier_->setEnabled(true); return 0; } /** * \var IPCUnixSocket::readyRead * \brief A Signal emitted when a message is ready to be read */ int IPCUnixSocket::sendData(const void *buffer, size_t length, const int32_t *fds, unsigned int num) { struct iovec iov[1]; iov[0].iov_base = const_cast<void *>(buffer); iov[0].iov_len = length; char buf[CMSG_SPACE(num * sizeof(uint32_t))]; memset(buf, 0, sizeof(buf)); struct cmsghdr *cmsg = (struct cmsghdr *)buf; cmsg->cmsg_len = CMSG_LEN(num * sizeof(uint32_t)); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; struct msghdr msg; msg.msg_name = nullptr; msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_control = cmsg; msg.msg_controllen = cmsg->cmsg_len; msg.msg_flags = 0; memcpy(CMSG_DATA(cmsg), fds, num * sizeof(uint32_t)); if (sendmsg(fd_, &msg, 0) < 0) { int ret = -errno; LOG(IPCUnixSocket, Error) << "Failed to sendmsg: " << strerror(-ret); return ret; } return 0; } int IPCUnixSocket::recvData(void *buffer, size_t length, int32_t *fds, unsigned int num) { struct iovec iov[1]; iov[0].iov_base = buffer; iov[0].iov_len = length; char buf[CMSG_SPACE(num * sizeof(uint32_t))]; memset(buf, 0, sizeof(buf)); struct cmsghdr *cmsg = (struct cmsghdr *)buf; cmsg->cmsg_len = CMSG_LEN(num * sizeof(uint32_t)); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; struct msghdr msg; msg.msg_name = nullptr; msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_control = cmsg; msg.msg_controllen = cmsg->cmsg_len; msg.msg_flags = 0; if (recvmsg(fd_, &msg, 0) < 0) { int ret = -errno; if (ret != -EAGAIN) LOG(IPCUnixSocket, Error) << "Failed to recvmsg: " << strerror(-ret); return ret; } memcpy(fds, CMSG_DATA(cmsg), num * sizeof(uint32_t)); return 0; } void IPCUnixSocket::dataNotifier(EventNotifier *notifier) { int ret; if (!headerReceived_) { /* Receive the header. */ ret = ::recv(fd_, &header_, sizeof(header_), 0); if (ret < 0) { ret = -errno; LOG(IPCUnixSocket, Error) << "Failed to receive header: " << strerror(-ret); return; } headerReceived_ = true; } /* * If the payload has arrived, disable the notifier and emit the * readyRead signal. The notifier will be reenabled by the receive() * method. */ struct pollfd fds = { fd_, POLLIN, 0 }; ret = poll(&fds, 1, 0); if (ret < 0) return; if (!(fds.revents & POLLIN)) return; notifier_->setEnabled(false); readyRead.emit(this); } } /* namespace libcamera */