From patchwork Tue Dec 1 17:43:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 10531 X-Patchwork-Delegate: kieran.bingham@ideasonboard.com Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id CE2DEBE177 for ; Tue, 1 Dec 2020 17:43:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9A54B63502; Tue, 1 Dec 2020 18:43:26 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=uajain.com header.i=@uajain.com header.b="o/Ed1NHY"; dkim-atps=neutral Received: from mail.uajain.com (static.126.159.217.95.clients.your-server.de [95.217.159.126]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7253663504 for ; Tue, 1 Dec 2020 18:43:24 +0100 (CET) From: Umang Jain DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=uajain.com; s=mail; t=1606844603; bh=oRjCMpNIRqSLO/uBfgIa8QnFPiHqODBbal+gfGMUfNA=; h=From:To:Cc:Subject:In-Reply-To:References; b=o/Ed1NHY8mKEVYLioE3WAvbNmAGyoWBm8oMkVP0bwdSP7LFVPBbVUvC74cAt/yUY9 5qG9Rk5Si/8qWPq3x3iTvkKXHD/Gt6xyJC65yLTDy0AlntlJiIuCZ8XuAMtOsSVmfS kICUyLy3DZWNVyMfk7bkGTLOhExaXnVLOW6JQO2s+/NHcEa9QRKQ7d254m5yvtOJqS W9j+vLvXeOI+OsdZ/4qpeemg0Iu6Xv/safl+MC0Z7BC4cvnjCCTJsCnAkd25ptM8jD OnDieR6rRhlW8dqmQecH5fv8/sKxcYDxvg0g+AQsmf2JkiPHo28EUtFHCeAKrqMlpb sRMqvw/ufsbvg== To: libcamera-devel@lists.libcamera.org Date: Tue, 1 Dec 2020 23:13:11 +0530 Message-Id: <20201201174314.12774-2-email@uajain.com> In-Reply-To: <20201201174314.12774-1-email@uajain.com> References: <20201201174314.12774-1-email@uajain.com> Mime-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 1/4] simple-cam: Make return codes consistent for main() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Use EXIT_FAILURE or EXIT_SUCCESS to indicate program execution status. These are the return codes that should be used for main() as per the C++ standard. Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart --- simple-cam.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/simple-cam.cpp b/simple-cam.cpp index 727bb6d..e88fb85 100644 --- a/simple-cam.cpp +++ b/simple-cam.cpp @@ -184,7 +184,7 @@ int main() int ret = camera->configure(config.get()); if (ret) { std::cout << "CONFIGURATION FAILED!" << std::endl; - return -1; + return EXIT_FAILURE; } #endif @@ -217,7 +217,7 @@ int main() int ret = allocator->allocate(cfg.stream()); if (ret < 0) { std::cerr << "Can't allocate buffers" << std::endl; - return -ENOMEM; + return EXIT_FAILURE; } unsigned int allocated = allocator->buffers(cfg.stream()).size(); @@ -250,7 +250,7 @@ int main() if (!request) { std::cerr << "Can't create request" << std::endl; - return -ENOMEM; + return EXIT_FAILURE; } const std::unique_ptr &buffer = buffers[i]; @@ -259,7 +259,7 @@ int main() { std::cerr << "Can't set buffer for request" << std::endl; - return ret; + return EXIT_FAILURE; } /* @@ -341,5 +341,5 @@ int main() camera.reset(); cm->stop(); - return 0; + return EXIT_SUCCESS; } From patchwork Tue Dec 1 17:43:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 10532 X-Patchwork-Delegate: kieran.bingham@ideasonboard.com Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 315F6BE177 for ; Tue, 1 Dec 2020 17:43:29 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id F300263501; Tue, 1 Dec 2020 18:43:28 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=uajain.com header.i=@uajain.com header.b="Z0hx+GmP"; dkim-atps=neutral Received: from mail.uajain.com (static.126.159.217.95.clients.your-server.de [95.217.159.126]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B46D063507 for ; Tue, 1 Dec 2020 18:43:26 +0100 (CET) From: Umang Jain DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=uajain.com; s=mail; t=1606844606; bh=YAuSE3bVoLNbDSNWm9ijG9eds7l5IqipAYA/Mq5598E=; h=From:To:Cc:Subject:In-Reply-To:References; b=Z0hx+GmP3FYr8pa3Z3IBJkgzZc+iuuurhBesf/hfFlpJ6Dd3kg7d+L3mUzyVpf6KT XAH32pJNk5J/FwIRjgC+0CYU+S/1xoRIModw8mEbOYcF9BqNxThL9x1fp87vZlUGj7 jueVxyUrMN1MaQ/Jfa5x6VDG6bx2rTP84COhb6V5RKIqKxnRQsE14xjesK2YL8Fuyx TXlfXiZgftBD6sQbkDpnhEj63ec9kOlMX1Y9YkXWgFJndzYZA8Bl9Olh6xOahxN9IH +nZzcjrFsEmXG2TVxvPeQ5HV9gQrdzA1RBW5/p30fZwmth8plg8z3PWKssVDawf6Ic EdjwLvSfiIhDQ== To: libcamera-devel@lists.libcamera.org Date: Tue, 1 Dec 2020 23:13:12 +0530 Message-Id: <20201201174314.12774-3-email@uajain.com> In-Reply-To: <20201201174314.12774-1-email@uajain.com> References: <20201201174314.12774-1-email@uajain.com> Mime-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/4] simple-cam: Early return if no cameras are found on the system. X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Failing to do so, the codepath will segfault while trying to acquire a non-existent camera. Signed-off-by: Umang Jain Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- simple-cam.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/simple-cam.cpp b/simple-cam.cpp index e88fb85..f844ff4 100644 --- a/simple-cam.cpp +++ b/simple-cam.cpp @@ -307,6 +307,13 @@ int main() for (std::unique_ptr &request : requests) camera->queueRequest(request.get()); + if(!cm->cameras().size()) { + std::cout << "No cameras were identified on the system." + << std::endl; + cm->stop(); + return EXIT_FAILURE; + } + /* * -------------------------------------------------------------------- * Run an EventLoop From patchwork Tue Dec 1 17:43:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 10533 X-Patchwork-Delegate: kieran.bingham@ideasonboard.com Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 85DA7BE177 for ; Tue, 1 Dec 2020 17:43:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5107563502; Tue, 1 Dec 2020 18:43:30 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=uajain.com header.i=@uajain.com header.b="myZCWcRt"; dkim-atps=neutral Received: from mail.uajain.com (static.126.159.217.95.clients.your-server.de [95.217.159.126]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2A71263509 for ; Tue, 1 Dec 2020 18:43:29 +0100 (CET) From: Umang Jain DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=uajain.com; s=mail; t=1606844608; bh=caM5SnBep/wP84bssQFFv2A/cZXJygdFIpjrpebMaVg=; h=From:To:Cc:Subject:In-Reply-To:References; b=myZCWcRtul63DfbBzXy+sLzsYGmwr2ugqAzEujF/K2XGnV6x+MB42vx9IbCKVUXhs Kpf5It43lEFkyxTOauI6eor9fAZFSgb6sH88sQZ6z5MdanCcsy7JwLw6gnwhvcB6rK x88ADC9vf3hqkFC7+cmm2APdYAcxMw+MTaNVzqT9MtMobY1RQZnWjDmrLHzIlBRDQd oCsoRj97JZ8kRD87Atfjx0sYiVWaQW1ndaAFx+/uKpkm5WWCOJKN604+iOiRwOeWjo ad98yG3DpUN36JY/lPFq3f9Zn5lU5YH5GwGbyr1O5vdNd3WolmMreV6jyMfAQwx6Gp +VrxnldqfACQQ== To: libcamera-devel@lists.libcamera.org Date: Tue, 1 Dec 2020 23:13:13 +0530 Message-Id: <20201201174314.12774-4-email@uajain.com> In-Reply-To: <20201201174314.12774-1-email@uajain.com> References: <20201201174314.12774-1-email@uajain.com> Mime-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 3/4] simple-cam: Fix documentation typo X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- simple-cam.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simple-cam.cpp b/simple-cam.cpp index f844ff4..0e26895 100644 --- a/simple-cam.cpp +++ b/simple-cam.cpp @@ -319,7 +319,7 @@ int main() * Run an EventLoop * * In order to dispatch events received from the video devices, such - * as buffer completions, an even loop as to be run. + * as buffer completions, an event loop has to be run. * * Libcamera provides its own default event dispatcher realized by * polling a set of file descriptors, but applications can integrate From patchwork Tue Dec 1 17:43:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 10534 X-Patchwork-Delegate: kieran.bingham@ideasonboard.com Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id E0AEEBE177 for ; Tue, 1 Dec 2020 17:43:33 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AB16063501; Tue, 1 Dec 2020 18:43:33 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=uajain.com header.i=@uajain.com header.b="jlpPDv5f"; dkim-atps=neutral Received: from mail.uajain.com (static.126.159.217.95.clients.your-server.de [95.217.159.126]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D227163460 for ; Tue, 1 Dec 2020 18:43:31 +0100 (CET) From: Umang Jain DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=uajain.com; s=mail; t=1606844611; bh=pNoQ0U/VmFqQ14vuFDziSpJb3Gj2Au/s+/uuIPwLXPo=; h=From:To:Cc:Subject:In-Reply-To:References; b=jlpPDv5fN34w3KaHw5m3vlU+x9LVKBa/1vdn5soFln5VXmPLPL7RkYMTrIeKrXyUi mfSE8G6jzfg9czvxBHgM8TeDi556ca/OZ+6I1WboVPpwJfbkhjDFdyldHtGO3k8Pku 8ZvFca+HHRjZiyAZWC+ZriMqK9tOJnvJtUjlLqH2OttRXAPv5TsgaHuvHbSzsW4nwA ti2kARJVeNoLi/K6Ylgv3O6uif/7gVS9f7eNrjZiA5WzaTrbCjYINyJ/kONUr2wCKf 6osqhtlUsNfzhEtyE8VsqW+6rRFbajOe6bOvQbpN/ntpZQVpMmA1bWn94BFbFCgIae 9vSR2ilpbljBg== To: libcamera-devel@lists.libcamera.org Date: Tue, 1 Dec 2020 23:13:14 +0530 Message-Id: <20201201174314.12774-5-email@uajain.com> In-Reply-To: <20201201174314.12774-1-email@uajain.com> References: <20201201174314.12774-1-email@uajain.com> Mime-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 4/4] simple-cam: Provide event-loop backed by libevent X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" libcamera moved its EventDispatcher and Timer API to its internal API, since providing an event loop to applications should not be the job of libcamera. Application utility like cam, were ported to use libevent, hence inspired from that, un-break simple-cam by using the similar implementation to replace the EventDispatcher and Timer functionality by libevent. Signed-off-by: Umang Jain --- meson.build | 1 + simple-cam.cpp | 101 +++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 91 insertions(+), 11 deletions(-) diff --git a/meson.build b/meson.build index c312f2c..0eca0a1 100644 --- a/meson.build +++ b/meson.build @@ -14,6 +14,7 @@ src_files = files([ # libcamera install path camera.pc file ($prefix/lib/pkgconfig/camera.pc) libcamera_deps = [ dependency('camera', required : true), + dependency('libevent_pthreads', required : true), ] cpp_arguments = [ '-Wno-unused-parameter', ] diff --git a/simple-cam.cpp b/simple-cam.cpp index 0e26895..dd785fc 100644 --- a/simple-cam.cpp +++ b/simple-cam.cpp @@ -8,12 +8,58 @@ #include #include #include +#include + +#include +#include #include +#define TIMEOUT_SEC 3 + using namespace libcamera; std::shared_ptr camera; +/* + * -------------------------------------------------------------------- + * Helper functions to interact and control the event loop. + * \todo Split event loop handling to a separate class and file. + */ +bool capture = true; +std::mutex lock; +std::list> calls_; +struct event_base *event; + +void interrupt() +{ + event_base_loopbreak(event); +} + +void callLater(const std::function &func) +{ + { + std::unique_lock locker(lock); + calls_.push_back(func); + } + + interrupt(); +} + +void dispatchCalls() +{ + std::unique_lock locker(lock); + + for (auto iter = calls_.begin(); iter != calls_.end(); ) { + std::function call = std::move(*iter); + + iter = calls_.erase(iter); + + locker.unlock(); + call(); + locker.lock(); + } +} + /* * -------------------------------------------------------------------- * Handle RequestComplete @@ -21,13 +67,26 @@ std::shared_ptr camera; * For each Camera::requestCompleted Signal emitted from the Camera the * connected Slot is invoked. * + * The Slot is invoked in the CameraManager's thread, hence one should avoid + * any heavy processing here. The processing of the request shall be re-directed + * to the application's thread instead, so as not to block the CameraManager's + * thread for large amount of time. + * * The Slot receives the Request as a parameter. */ + +static void processRequest(Request *request); + static void requestComplete(Request *request) { if (request->status() == Request::RequestCancelled) return; + callLater(std::bind(&processRequest, request)); +} + +static void processRequest(Request *request) +{ const Request::BufferMap &buffers = request->buffers(); for (auto bufferPair : buffers) { @@ -60,6 +119,15 @@ static void requestComplete(Request *request) camera->queueRequest(request); } +void timeoutTriggered(int fd, short event, void *arg) +{ + capture = false; + interrupt(); + + std::cout << "Capture ran for " << TIMEOUT_SEC << " seconds, Exiting." + << std::endl; +} + int main() { /* @@ -321,18 +389,25 @@ int main() * In order to dispatch events received from the video devices, such * as buffer completions, an event loop has to be run. * - * Libcamera provides its own default event dispatcher realized by - * polling a set of file descriptors, but applications can integrate - * their own even loop with the Libcamera EventDispatcher. - * - * Here, as an example, run the poll-based EventDispatcher for 3 - * seconds. + * simple-cam uses a base event loop provided by libevent, which is run + * for TIMEOUT_SEC seconds after which, the event loop is interrupted + * via interrupt() and begins the cleanup. The interval for which the + * event loop is being run, completed requests are processed via + * requestComplete() handler. */ - EventDispatcher *dispatcher = cm->eventDispatcher(); - Timer timer; - timer.start(3000); - while (timer.isRunning()) - dispatcher->processEvents(); + struct event *ev; + struct timeval tv; + + tv.tv_sec = TIMEOUT_SEC; + tv.tv_usec = 0; + evthread_use_pthreads(); + event = event_base_new(); + ev = event_new(event, -1, EV_TIMEOUT, &timeoutTriggered, NULL); + event_add(ev, &tv); + while (capture) { + dispatchCalls(); + event_base_loop(event, EVLOOP_NO_EXIT_ON_EMPTY); + } /* * -------------------------------------------------------------------- @@ -341,6 +416,10 @@ int main() * Stop the Camera, release resources and stop the CameraManager. * Libcamera has now released all resources it owned. */ + event_free(ev); + event_base_free(event); + libevent_global_shutdown(); + camera->stop(); allocator->free(stream); delete allocator;