[{"id":23571,"web_url":"https://patchwork.libcamera.org/comment/23571/","msgid":"<165606820766.1149771.3192523452540544185@Monstersaurus>","date":"2022-06-24T10:56:47","subject":"Re: [libcamera-devel] [RFC v1 7/7] py: cam.py: Use new events\n\tsupport","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Tomi Valkeinen (2022-06-23 15:47:36)\n> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n> ---\n>  src/py/cam/cam.py | 31 +++++++++++++++++++++++++------\n>  1 file changed, 25 insertions(+), 6 deletions(-)\n> \n> diff --git a/src/py/cam/cam.py b/src/py/cam/cam.py\n> index 733e9ae5..538f0c1d 100755\n> --- a/src/py/cam/cam.py\n> +++ b/src/py/cam/cam.py\n> @@ -243,11 +243,7 @@ class CaptureState:\n>      # Called from renderer when there is a libcamera event\n>      def event_handler(self):\n>          try:\n> -            reqs = self.cm.get_ready_requests()\n> -\n> -            for req in reqs:\n> -                ctx = next(ctx for ctx in self.contexts if ctx.idx == req.cookie)\n> -                self.__request_handler(ctx, req)\n> +            self.cm.dispatch_events()\n>  \n>              running = any(ctx.reqs_completed < ctx.opt_capture for ctx in self.contexts)\n>              return running\n> @@ -255,7 +251,9 @@ class CaptureState:\n>              traceback.print_exc()\n>              return False\n>  \n> -    def __request_handler(self, ctx, req):\n> +    def __request_handler(self, cam, req):\n> +        ctx = next(ctx for ctx in self.contexts if ctx.camera == cam)\n> +\n>          if req.status != libcam.Request.Status.Complete:\n>              raise Exception('{}: Request failed: {}'.format(ctx.id, req.status))\n>  \n> @@ -310,6 +308,9 @@ class CaptureState:\n>              ctx.camera.queue_request(req)\n>              ctx.reqs_queued += 1\n>  \n> +    def __disconnect_handler(self, cam):\n> +        print('Camera', cam, 'disconnected')\n> +\n>      def __capture_init(self):\n>          for ctx in self.contexts:\n>              ctx.acquire()\n> @@ -323,6 +324,15 @@ class CaptureState:\n>          for ctx in self.contexts:\n>              ctx.create_requests()\n>  \n> +        for ctx in self.contexts:\n> +            # These cause circular dependencies:\n> +            # The callback in the camera points to CaptureState.\n> +            # The CaptureState points to the camera.\n> +            # This can be solved by setting the callbacks to None after stopping\n> +            # or using lambdas here and weakref.WeakMethod.\n\nI wish I could comment here, but I've got nothing specific or useful :S\n\n> +            ctx.camera.request_completed = self.__request_handler\n> +            ctx.camera.disconnected = self.__disconnect_handler\n> +\n>      def __capture_start(self):\n>          for ctx in self.contexts:\n>              ctx.start()\n> @@ -334,6 +344,10 @@ class CaptureState:\n>          for ctx in self.contexts:\n>              ctx.stop()\n>  \n> +        for ctx in self.contexts:\n> +            ctx.camera.request_completed = None\n> +            ctx.camera.disconnected = None\n> +\n>          for ctx in self.contexts:\n>              ctx.release()\n>  \n> @@ -402,6 +416,9 @@ def main():\n>  \n>      cm = libcam.CameraManager.singleton()\n>  \n> +    cm.camera_added = lambda c: print(\"Camera added:\", c)\n> +    cm.camera_removed = lambda c: print(\"Camera removed:\", c)\n> +\n>      if args.list:\n>          do_cmd_list(cm)\n>  \n> @@ -459,6 +476,8 @@ def main():\n>  \n>          state.do_cmd_capture()\n>  \n> +        cm.discard_events()\n> +\n>      return 0\n>  \n>  \n> -- \n> 2.34.1\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 207A0BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 24 Jun 2022 10:56:53 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 5E2E465637;\n\tFri, 24 Jun 2022 12:56:52 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 92B0A600EC\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 24 Jun 2022 12:56:50 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id F3083DD;\n\tFri, 24 Jun 2022 12:56:49 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656068212;\n\tbh=nadRBqpIPSKs7K0c0CnjvSI3xYE2WK/8vysHPBuKrPU=;\n\th=In-Reply-To:References:To:Date:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=28BXKqzAXSdyCJykP69OmOwgRR+sTJOnTpq8fxOE+zoawcF1pGrudzglOKawUvs6J\n\t7+A0noaqgE6P7O+KDd0zimPthKkwI8JND/3Rkti8CmGWt3O+JnvSWC0NsthFtSja9j\n\tl8R0cjxAeD2lWNghYOCWfxhjMow9yNLSo9g0kuixRqwfdaaXFkW2ZdVQp20R7N+bX5\n\tnDF0YYRXQF6S4lTPINZqlWcSuvE1PSN0+nFH3tqqEwiSmOeBI722pqLhGtvpeLVrFc\n\tzAB6TmPl/6Tu4TCzMt4xELpQt6eZpQyhji3/tQupy4ug8sYbg4W8EDQrTCM5idBWrl\n\tnDqJ7mr7rUx6g==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656068210;\n\tbh=nadRBqpIPSKs7K0c0CnjvSI3xYE2WK/8vysHPBuKrPU=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=E66rIy6ht4XCrGO1rlvpOhIrpVJy1X5htgkvHVwFE0706sDfV9MGiMFNdyQzR47Gf\n\t7n9L/Mrk5aEZG79EYPgPgmsW8jhn7pXidXJ9suHvVaSIltjsjWb0RFFNfvXGgVS2sN\n\tr7ULjJjD8U9WmKXBaOK9rI18WcKSQtmrh4iOWjxY="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"E66rIy6h\"; dkim-atps=neutral","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20220623144736.78537-8-tomi.valkeinen@ideasonboard.com>","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-8-tomi.valkeinen@ideasonboard.com>","To":"David Plowman <david.plowman@raspberrypi.com>,\n\tJacopo Mondi <jacopo@jmondi.org>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tTomi Valkeinen <tomi.valkeinen@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Fri, 24 Jun 2022 11:56:47 +0100","Message-ID":"<165606820766.1149771.3192523452540544185@Monstersaurus>","User-Agent":"alot/0.10","Subject":"Re: [libcamera-devel] [RFC v1 7/7] py: cam.py: Use new events\n\tsupport","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","From":"Kieran Bingham via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23579,"web_url":"https://patchwork.libcamera.org/comment/23579/","msgid":"<YrXEAn2I1gVhsTnO@pendragon.ideasonboard.com>","date":"2022-06-24T14:02:42","subject":"Re: [libcamera-devel] [RFC v1 7/7] py: cam.py: Use new events\n\tsupport","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Tomi,\n\nThank you for the patch.\n\nOn Thu, Jun 23, 2022 at 05:47:36PM +0300, Tomi Valkeinen wrote:\n\nMaybe a commit message ?\n\n> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n> ---\n>  src/py/cam/cam.py | 31 +++++++++++++++++++++++++------\n>  1 file changed, 25 insertions(+), 6 deletions(-)\n> \n> diff --git a/src/py/cam/cam.py b/src/py/cam/cam.py\n> index 733e9ae5..538f0c1d 100755\n> --- a/src/py/cam/cam.py\n> +++ b/src/py/cam/cam.py\n> @@ -243,11 +243,7 @@ class CaptureState:\n>      # Called from renderer when there is a libcamera event\n>      def event_handler(self):\n>          try:\n> -            reqs = self.cm.get_ready_requests()\n> -\n> -            for req in reqs:\n> -                ctx = next(ctx for ctx in self.contexts if ctx.idx == req.cookie)\n> -                self.__request_handler(ctx, req)\n> +            self.cm.dispatch_events()\n>  \n>              running = any(ctx.reqs_completed < ctx.opt_capture for ctx in self.contexts)\n>              return running\n> @@ -255,7 +251,9 @@ class CaptureState:\n>              traceback.print_exc()\n>              return False\n>  \n> -    def __request_handler(self, ctx, req):\n> +    def __request_handler(self, cam, req):\n> +        ctx = next(ctx for ctx in self.contexts if ctx.camera == cam)\n> +\n>          if req.status != libcam.Request.Status.Complete:\n>              raise Exception('{}: Request failed: {}'.format(ctx.id, req.status))\n>  \n> @@ -310,6 +308,9 @@ class CaptureState:\n>              ctx.camera.queue_request(req)\n>              ctx.reqs_queued += 1\n>  \n> +    def __disconnect_handler(self, cam):\n> +        print('Camera', cam, 'disconnected')\n\nI thought you were a fan of Python string formatting ? :-)\n\n        print(f'Camera {cam} disconnected')\n\n> +\n>      def __capture_init(self):\n>          for ctx in self.contexts:\n>              ctx.acquire()\n> @@ -323,6 +324,15 @@ class CaptureState:\n>          for ctx in self.contexts:\n>              ctx.create_requests()\n>  \n> +        for ctx in self.contexts:\n> +            # These cause circular dependencies:\n> +            # The callback in the camera points to CaptureState.\n> +            # The CaptureState points to the camera.\n> +            # This can be solved by setting the callbacks to None after stopping\n> +            # or using lambdas here and weakref.WeakMethod.\n> +            ctx.camera.request_completed = self.__request_handler\n> +            ctx.camera.disconnected = self.__disconnect_handler\n> +\n>      def __capture_start(self):\n>          for ctx in self.contexts:\n>              ctx.start()\n> @@ -334,6 +344,10 @@ class CaptureState:\n>          for ctx in self.contexts:\n>              ctx.stop()\n>  \n> +        for ctx in self.contexts:\n> +            ctx.camera.request_completed = None\n> +            ctx.camera.disconnected = None\n> +\n>          for ctx in self.contexts:\n>              ctx.release()\n>  \n> @@ -402,6 +416,9 @@ def main():\n>  \n>      cm = libcam.CameraManager.singleton()\n>  \n> +    cm.camera_added = lambda c: print(\"Camera added:\", c)\n> +    cm.camera_removed = lambda c: print(\"Camera removed:\", c)\n\nSingle quotes.\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> +\n>      if args.list:\n>          do_cmd_list(cm)\n>  \n> @@ -459,6 +476,8 @@ def main():\n>  \n>          state.do_cmd_capture()\n>  \n> +        cm.discard_events()\n> +\n>      return 0\n>  \n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id C37ADBD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 24 Jun 2022 14:03:01 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 26ADE65635;\n\tFri, 24 Jun 2022 16:03:01 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 4070760412\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 24 Jun 2022 16:02:59 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 75AF547C;\n\tFri, 24 Jun 2022 16:02:58 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656079381;\n\tbh=7F6e2Yp8xff4UlW0rI1EBMxnEh+Rs1M4GIR1nEaW8gk=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=BeP6psKpLPV6AGKO0S63b0JBuILmMEYFKMV5xA7Rd8uGTZV9QgxUQeaqO3+Kj7bD6\n\tSeiTSXIo6QcJ+gIFoM5ptq41QS92Y7wdDmY3cvVu/2YkFVD5KUg9S04RJu43IBTEVY\n\th5vUnkBLdBS/Y4Gqmw1T0fSJvRl6uRNsCv8qsXUwjtv4RJaL2Z98309QzpWhdoTOA5\n\tGdosEPT9LExrybwT12Ymv+jQ4XLj/hn4bllCSfLXp2AVrhCHTNXezfcgl/lwrOVIVY\n\tr+ktFnFCzfUbEiVNG19uRoAl5nTPTZ85/qerBDuQtEQPR4QDK2jFPtMS/rtA8Uj4IY\n\tQds82s8ReKwQQ==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656079378;\n\tbh=7F6e2Yp8xff4UlW0rI1EBMxnEh+Rs1M4GIR1nEaW8gk=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=wp5Wf5la6kXATVJGETImn5+3PFvaS0etGdMTTXQaG6xeGbrmFJEfZmHKiHLMs6qNS\n\t5JUOMShliE5WEE1Htl2VXZ94WYXiLayX7NZGrHihrxKU3IS08owf6RSO6fdhWFM29D\n\tRyvwfEIRxQZwc8T2I2+jUo7Gdt1yNm6DC/rJBZvs="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"wp5Wf5la\"; dkim-atps=neutral","Date":"Fri, 24 Jun 2022 17:02:42 +0300","To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Message-ID":"<YrXEAn2I1gVhsTnO@pendragon.ideasonboard.com>","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-8-tomi.valkeinen@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20220623144736.78537-8-tomi.valkeinen@ideasonboard.com>","Subject":"Re: [libcamera-devel] [RFC v1 7/7] py: cam.py: Use new events\n\tsupport","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]