From patchwork Thu Nov 19 12:34:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 10447 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 F031CBE08A for ; Thu, 19 Nov 2020 12:34:38 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0166C615AA; Thu, 19 Nov 2020 13:34:38 +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="IAjwfltC"; 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 B1AF4615A3 for ; Thu, 19 Nov 2020 13:34:36 +0100 (CET) From: Umang Jain DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=uajain.com; s=mail; t=1605789276; bh=/smKCARF6HosYrSKrlAnihdgx7dKq8n6xByKatoxOqs=; h=From:To:Cc:Subject:In-Reply-To:References; b=IAjwfltCrVdIjk0CtKUFV/PX9jHvTKV8ZsSYmfUO1cHVAirXmYZrBzhuB+oRWIub+ qyCq18dB18qADwrwXDZ3Hznn1R+VvKmu9K3iIXvIuTkHJTUk68bOCeAH4ro04psJoh PXH2xljF56tHHgCik7GraYQNxJ7ZtoxJcuraE59OGbiaXP7CFNb9KuHT1J33d1G+q7 FEiCxeMzXqFkTB+EH2JgeqsGXiCXzzIqpmX3uau+lHrjI2FM18ZpX9mi7dbzRY+ZBX Z7JxmuXgjtZSy4/xtvb8QCvqfmWuLKVhbBwzwJa44aR4BBxtyQdMjX5asB6TcoLNVO +j/fWM5a6UYAA== To: libcamera-devel@lists.libcamera.org Date: Thu, 19 Nov 2020 18:04:24 +0530 Message-Id: <20201119123427.53864-2-email@uajain.com> In-Reply-To: <20201119123427.53864-1-email@uajain.com> References: <20201119123427.53864-1-email@uajain.com> Mime-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/3] 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 --- simple-cam.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/simple-cam.cpp b/simple-cam.cpp index 727bb6d..af9c8b1 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 -1; + } + /* * -------------------------------------------------------------------- * Run an EventLoop From patchwork Thu Nov 19 12:34:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 10448 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 93378BE08A for ; Thu, 19 Nov 2020 12:34:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6176D615A5; Thu, 19 Nov 2020 13:34:41 +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="D9kFDDak"; 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 478AE615A3 for ; Thu, 19 Nov 2020 13:34:39 +0100 (CET) From: Umang Jain DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=uajain.com; s=mail; t=1605789278; bh=sYGYQU7inBPH7AGvzhz7vvRZ9Gc2WnZ9N97seyqe5d4=; h=From:To:Cc:Subject:In-Reply-To:References; b=D9kFDDakeSX1GLBObSwxPk8RsQH3TyscOUTC0He1UMMPKYmprT9Yu1VhFvqsEnu7f SyqthV5Nxu3681Cn/+oN2eNGPqs3c8KKLLdl1lIP+oAyckuuhrWuGFO0cbmx+sqVtK SOSYlMcvlN1ZUFoEwElJR5oDdMaX5VH372cDV7Mf4w/OHWK09Vs27K3XXJpEDpXyLN ab4bnt0z/c+PR+Z7O9Vwtbm/fNaPVjVEn/MWl6W87NhPWl3JLO6GCeV+kxK/sOieWF rjd0elYtqEneczYzTf96XosXCO4GLkmVuG+Xcls+YITY1DyNO/D95Qm8H3hVBnlUkM sPc+uyAi7toew== To: libcamera-devel@lists.libcamera.org Date: Thu, 19 Nov 2020 18:04:25 +0530 Message-Id: <20201119123427.53864-3-email@uajain.com> In-Reply-To: <20201119123427.53864-1-email@uajain.com> References: <20201119123427.53864-1-email@uajain.com> Mime-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/3] 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: Kieran Bingham Reviewed-by: Laurent Pinchart --- simple-cam.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simple-cam.cpp b/simple-cam.cpp index af9c8b1..65e0f14 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 Thu Nov 19 12:34:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 10449 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 1931CBE08A for ; Thu, 19 Nov 2020 12:34:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DAC1D615AD; Thu, 19 Nov 2020 13:34:42 +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="JFRQiHOi"; 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 72E1B615AD for ; Thu, 19 Nov 2020 13:34:41 +0100 (CET) From: Umang Jain DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=uajain.com; s=mail; t=1605789280; bh=v29nXesu/z4NphJ0BC/9ln8uSCd+sbqWGuMlvhMLPME=; h=From:To:Cc:Subject:In-Reply-To:References; b=JFRQiHOi837J9HgZarzsivw49qBiH24vUVWz2IE2V7rMZnIudvxEEFgCA3tyVLrHD bYm+SLak+VmdLCo3srDgm50M75qg792pgltI/h6vgVw5E2j0+4ZPcPtleK/K64vhpH VYrrAhwVRtc3dExcwGktKCFh1c+HtPXO4GAoU6RM4n9eQWqdACV91NnBITUjztPFzt atUCpON1jfu47dNfGiAtqhrkAArcoa5NWwAlGAlvCJyA11z9WdQEoLkM/1ovzv4AfG L+MIbapro/6KKNclrYXsJv7x8MYqbiKdpoRJgNsp5fQDnBtYGOK7aoDd0KeOf/aXF2 /zNK5Uvt0n0Hw== To: libcamera-devel@lists.libcamera.org Date: Thu, 19 Nov 2020 18:04:26 +0530 Message-Id: <20201119123427.53864-4-email@uajain.com> In-Reply-To: <20201119123427.53864-1-email@uajain.com> References: <20201119123427.53864-1-email@uajain.com> Mime-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/3] 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 | 100 +++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 90 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 65e0f14..7fbb890 100644 --- a/simple-cam.cpp +++ b/simple-cam.cpp @@ -8,12 +8,57 @@ #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. + */ +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 +66,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 +118,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 +388,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 +415,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;