[{"id":11584,"web_url":"https://patchwork.libcamera.org/comment/11584/","msgid":"<20200724180059.GZ5921@pendragon.ideasonboard.com>","date":"2020-07-24T18:00:59","subject":"Re: [libcamera-devel] [PATCH v2 3/3] cam: Add optional argument to\n\t--capture to specify how many frames to capture","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Niklas,\n\nThank you for the patch.\n\nOn Fri, Jul 24, 2020 at 07:48:27PM +0200, Niklas Söderlund wrote:\n> Extend the '--capture' option with and optional numerical argument to be\n> able to specify how many frames to capture before exiting. If the\n> optional argument is not provided the old behavior of running until the\n> user interrupts with a SIGINT is retained.\n> \n> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> ---\n> * Changes since v1\n> - Extend --capture option instead of adding a new --count option.\n> ---\n>  src/cam/capture.cpp | 17 +++++++++++++++--\n>  src/cam/capture.h   |  2 ++\n>  src/cam/main.cpp    |  5 +++--\n>  3 files changed, 20 insertions(+), 4 deletions(-)\n> \n> diff --git a/src/cam/capture.cpp b/src/cam/capture.cpp\n> index aa53c407d7b71b44..2378c1c737e9f419 100644\n> --- a/src/cam/capture.cpp\n> +++ b/src/cam/capture.cpp\n> @@ -17,7 +17,8 @@\n>  using namespace libcamera;\n>  \n>  Capture::Capture(std::shared_ptr<Camera> camera, CameraConfiguration *config)\n> -\t: camera_(camera), config_(config), writer_(nullptr), loop_(nullptr)\n> +\t: camera_(camera), config_(config), writer_(nullptr), loop_(nullptr),\n> +\t  captureCount_(0), captureLimit_(0)\n>  {\n>  }\n>  \n> @@ -26,6 +27,8 @@ int Capture::run(EventLoop *loop, const OptionsParser::Options &options)\n>  \tint ret;\n>  \n>  \tloop_ = loop;\n> +\tcaptureCount_ = 0;\n> +\tcaptureLimit_ = options[OptCapture].toInteger();\n>  \n>  \tif (!camera_) {\n>  \t\tstd::cout << \"Can't capture without a camera\" << std::endl;\n> @@ -133,7 +136,11 @@ int Capture::capture(FrameBufferAllocator *allocator)\n>  \t\t}\n>  \t}\n>  \n> -\tstd::cout << \"Capture until user interrupts by SIGINT\" << std::endl;\n> +\tif (captureLimit_)\n> +\t\tstd::cout << \"Capture \" << captureLimit_ << \" frames\" << std::endl;\n> +\telse\n> +\t\tstd::cout << \"Capture until user interrupts by SIGINT\" << std::endl;\n> +\n>  \tret = loop_->exec();\n>  \tif (ret)\n>  \t\tstd::cout << \"Failed to run capture loop\" << std::endl;\n> @@ -202,5 +209,11 @@ void Capture::requestComplete(Request *request)\n>  \t\trequest->addBuffer(stream, buffer);\n>  \t}\n>  \n> +\tcaptureCount_++;\n> +\tif (captureLimit_ && captureCount_ >= captureLimit_) {\n> +\t\tloop_->exit(0);\n> +\t\treturn;\n> +\t}\n\nShould this go a bit above, just before creating the new request ?\nOtherwise you'll leak it. Could you please test this series with\nvalgrind ?\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> +\n>  \tcamera_->queueRequest(request);\n>  }\n> diff --git a/src/cam/capture.h b/src/cam/capture.h\n> index 67c6260bfe24aefc..0a1cbc519f2a90c5 100644\n> --- a/src/cam/capture.h\n> +++ b/src/cam/capture.h\n> @@ -40,6 +40,8 @@ private:\n>  \tstd::chrono::steady_clock::time_point last_;\n>  \n>  \tEventLoop *loop_;\n> +\tunsigned int captureCount_;\n> +\tunsigned int captureLimit_;\n>  };\n>  \n>  #endif /* __CAM_CAPTURE_H__ */\n> diff --git a/src/cam/main.cpp b/src/cam/main.cpp\n> index 2009f11b6c336f2c..adbb1c657de0f053 100644\n> --- a/src/cam/main.cpp\n> +++ b/src/cam/main.cpp\n> @@ -167,8 +167,9 @@ int CamApp::parseOptions(int argc, char *argv[])\n>  \tparser.addOption(OptCamera, OptionString,\n>  \t\t\t \"Specify which camera to operate on, by name or by index\", \"camera\",\n>  \t\t\t ArgumentRequired, \"camera\");\n> -\tparser.addOption(OptCapture, OptionNone,\n> -\t\t\t \"Capture until interrupted by user\", \"capture\");\n> +\tparser.addOption(OptCapture, OptionInteger,\n> +\t\t\t \"Capture until interrupted by user or until <count> frames captured\",\n> +\t\t\t \"capture\", ArgumentOptional, \"count\");\n>  \tparser.addOption(OptFile, OptionString,\n>  \t\t\t \"Write captured frames to disk\\n\"\n>  \t\t\t \"The first '#' character in the file name is expanded to the stream name and frame sequence number.\\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 145AABD86F\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 24 Jul 2020 18:01:09 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 89B1B6121D;\n\tFri, 24 Jul 2020 20:01:08 +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 2ED366039B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 24 Jul 2020 20:01:07 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id A827E538;\n\tFri, 24 Jul 2020 20:01:06 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Ofy5h8Gb\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1595613666;\n\tbh=65RuSQ2WqkB51V9m7WBcTWA3ni2GXDyNaAgLulLs6Rw=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=Ofy5h8GbdtMYGInpHiZzJngCSlw+qoEsNi1ulGfegHU1fxHL49jxI0j9/Os5HGl7O\n\tCWECSA4C5Y5hBrOxFqq3PwZQ5vgjl3iPW2+h+FfiATAWk23UAch+xehlWKSyw2xalR\n\t59OTgWv8P3IVxh/eTfepBr7ZY7P+y1D3htcRRezc=","Date":"Fri, 24 Jul 2020 21:00:59 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Niklas =?utf-8?q?S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","Message-ID":"<20200724180059.GZ5921@pendragon.ideasonboard.com>","References":"<20200724174827.757493-1-niklas.soderlund@ragnatech.se>\n\t<20200724174827.757493-4-niklas.soderlund@ragnatech.se>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200724174827.757493-4-niklas.soderlund@ragnatech.se>","Subject":"Re: [libcamera-devel] [PATCH v2 3/3] cam: Add optional argument to\n\t--capture to specify how many frames to capture","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>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"base64","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":11587,"web_url":"https://patchwork.libcamera.org/comment/11587/","msgid":"<20200724191521.GD2729799@oden.dyn.berto.se>","date":"2020-07-24T19:15:21","subject":"Re: [libcamera-devel] [PATCH v2 3/3] cam: Add optional argument to\n\t--capture to specify how many frames to capture","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Laurent,\n\nThanks for your comments.\n\nOn 2020-07-24 21:00:59 +0300, Laurent Pinchart wrote:\n> Hi Niklas,\n> \n> Thank you for the patch.\n> \n> On Fri, Jul 24, 2020 at 07:48:27PM +0200, Niklas Söderlund wrote:\n> > Extend the '--capture' option with and optional numerical argument to be\n> > able to specify how many frames to capture before exiting. If the\n> > optional argument is not provided the old behavior of running until the\n> > user interrupts with a SIGINT is retained.\n> > \n> > Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> > ---\n> > * Changes since v1\n> > - Extend --capture option instead of adding a new --count option.\n> > ---\n> >  src/cam/capture.cpp | 17 +++++++++++++++--\n> >  src/cam/capture.h   |  2 ++\n> >  src/cam/main.cpp    |  5 +++--\n> >  3 files changed, 20 insertions(+), 4 deletions(-)\n> > \n> > diff --git a/src/cam/capture.cpp b/src/cam/capture.cpp\n> > index aa53c407d7b71b44..2378c1c737e9f419 100644\n> > --- a/src/cam/capture.cpp\n> > +++ b/src/cam/capture.cpp\n> > @@ -17,7 +17,8 @@\n> >  using namespace libcamera;\n> >  \n> >  Capture::Capture(std::shared_ptr<Camera> camera, CameraConfiguration *config)\n> > -\t: camera_(camera), config_(config), writer_(nullptr), loop_(nullptr)\n> > +\t: camera_(camera), config_(config), writer_(nullptr), loop_(nullptr),\n> > +\t  captureCount_(0), captureLimit_(0)\n> >  {\n> >  }\n> >  \n> > @@ -26,6 +27,8 @@ int Capture::run(EventLoop *loop, const OptionsParser::Options &options)\n> >  \tint ret;\n> >  \n> >  \tloop_ = loop;\n> > +\tcaptureCount_ = 0;\n> > +\tcaptureLimit_ = options[OptCapture].toInteger();\n> >  \n> >  \tif (!camera_) {\n> >  \t\tstd::cout << \"Can't capture without a camera\" << std::endl;\n> > @@ -133,7 +136,11 @@ int Capture::capture(FrameBufferAllocator *allocator)\n> >  \t\t}\n> >  \t}\n> >  \n> > -\tstd::cout << \"Capture until user interrupts by SIGINT\" << std::endl;\n> > +\tif (captureLimit_)\n> > +\t\tstd::cout << \"Capture \" << captureLimit_ << \" frames\" << std::endl;\n> > +\telse\n> > +\t\tstd::cout << \"Capture until user interrupts by SIGINT\" << std::endl;\n> > +\n> >  \tret = loop_->exec();\n> >  \tif (ret)\n> >  \t\tstd::cout << \"Failed to run capture loop\" << std::endl;\n> > @@ -202,5 +209,11 @@ void Capture::requestComplete(Request *request)\n> >  \t\trequest->addBuffer(stream, buffer);\n> >  \t}\n> >  \n> > +\tcaptureCount_++;\n> > +\tif (captureLimit_ && captureCount_ >= captureLimit_) {\n> > +\t\tloop_->exit(0);\n> > +\t\treturn;\n> > +\t}\n> \n> Should this go a bit above, just before creating the new request ?\n> Otherwise you'll leak it. Could you please test this series with\n> valgrind ?\n\nWoops, thanks for spotting this! You are correct valgrind warns for this \nfault while moving it as you suggest solves it.\n\n> \n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> \n> > +\n> >  \tcamera_->queueRequest(request);\n> >  }\n> > diff --git a/src/cam/capture.h b/src/cam/capture.h\n> > index 67c6260bfe24aefc..0a1cbc519f2a90c5 100644\n> > --- a/src/cam/capture.h\n> > +++ b/src/cam/capture.h\n> > @@ -40,6 +40,8 @@ private:\n> >  \tstd::chrono::steady_clock::time_point last_;\n> >  \n> >  \tEventLoop *loop_;\n> > +\tunsigned int captureCount_;\n> > +\tunsigned int captureLimit_;\n> >  };\n> >  \n> >  #endif /* __CAM_CAPTURE_H__ */\n> > diff --git a/src/cam/main.cpp b/src/cam/main.cpp\n> > index 2009f11b6c336f2c..adbb1c657de0f053 100644\n> > --- a/src/cam/main.cpp\n> > +++ b/src/cam/main.cpp\n> > @@ -167,8 +167,9 @@ int CamApp::parseOptions(int argc, char *argv[])\n> >  \tparser.addOption(OptCamera, OptionString,\n> >  \t\t\t \"Specify which camera to operate on, by name or by index\", \"camera\",\n> >  \t\t\t ArgumentRequired, \"camera\");\n> > -\tparser.addOption(OptCapture, OptionNone,\n> > -\t\t\t \"Capture until interrupted by user\", \"capture\");\n> > +\tparser.addOption(OptCapture, OptionInteger,\n> > +\t\t\t \"Capture until interrupted by user or until <count> frames captured\",\n> > +\t\t\t \"capture\", ArgumentOptional, \"count\");\n> >  \tparser.addOption(OptFile, OptionString,\n> >  \t\t\t \"Write captured frames to disk\\n\"\n> >  \t\t\t \"The first '#' character in the file name is expanded to the stream name and frame sequence number.\\n\"\n> \n> -- \n> Regards,\n> \n> Laurent Pinchart","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 E6E71BD878\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 24 Jul 2020 19:15:25 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 61DF76121D;\n\tFri, 24 Jul 2020 21:15:25 +0200 (CEST)","from mail-lf1-x143.google.com (mail-lf1-x143.google.com\n\t[IPv6:2a00:1450:4864:20::143])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 713FE6039B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 24 Jul 2020 21:15:23 +0200 (CEST)","by mail-lf1-x143.google.com with SMTP id u12so5760695lff.2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 24 Jul 2020 12:15:23 -0700 (PDT)","from localhost (h-209-203.A463.priv.bahnhof.se. [155.4.209.203])\n\tby smtp.gmail.com with ESMTPSA id\n\tg24sm428638ljl.139.2020.07.24.12.15.21\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tFri, 24 Jul 2020 12:15:21 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=ragnatech-se.20150623.gappssmtp.com\n\theader.i=@ragnatech-se.20150623.gappssmtp.com\n\theader.b=\"OmSpSFHh\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to;\n\tbh=DO2XfGh18aI475laKauLuDgV+Mms3/0TTXGOxnk6rwk=;\n\tb=OmSpSFHh1mX1QV96RLtFVv+7o0x5wix6yhLjgjt6aF0TwZQFEaeOnOHVvR6B8gwp8W\n\t4eA+D4t+gg1mZhhEP5v0k2uTi7E3/KEEPI+z7wwmszeQjBNLU0eCZfHyUu7SsBuuxCSV\n\tldFfJuExC3+bO61lXuFjc2qULYPnlbA3647LY59v4xsSG4twhli9JceUBFEoJqJot3ic\n\trXxiETY8hfOxFf2DH3QW3O7/6TCOMAK95InRx2ZIG8Ar2MBKJTKPg0a5/HSCzrqxE4vv\n\te9NKNCmtWZXssCyQbHCGpz74Y0s8wGMJPobEOka4bQhr+mDXD9txQHL5BmqkPiP9W5I4\n\tF2MQ==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to;\n\tbh=DO2XfGh18aI475laKauLuDgV+Mms3/0TTXGOxnk6rwk=;\n\tb=BLbHBAZLE7tdHZUhOKJOYmh2eHY5x9m4St2u1KRq50CY8hSpFgl/YcUsEuiggQ+dgL\n\tkwXROibjIB4uspFgpGmrHzevvtsmplpmN+980PBbJO9asbdUaPfRx9cBPc89JUH3dd4i\n\tMU2ETjND/sVmMmKvoG7KHqjk6OHfMZgv0RZApsaUHWiS4hBx0+HhtOK4K1H57ClBmLHr\n\tM68hIV5OpeQwkg+f5+LNZriGL8fNZ/OX/lU9ddcbNqnc/k8hf3jnkQ1NKO+UikNr6YkD\n\tnp8xHPCtqD5aORXaLirJSMPGk2esQnjwr7/oXE0iTBDwLLfLaFP/ZXsmNEVoenrFGEE8\n\tpyvA==","X-Gm-Message-State":"AOAM533ASsZWu2NE6X5m/zbgJJZzm41ri/R9yT3UFXiySQZJ0ED6COjh\n\tuqk8hrmYKy+1GGeGF7yVtfBhDLRt2Qs=","X-Google-Smtp-Source":"ABdhPJzm0IKtuVTf2EYn62i+n4WsfigLjktAfErY1VPfPqRg3tYhGZrsrz5IXoTlAUsXDu82q9SXsA==","X-Received":"by 2002:ac2:5335:: with SMTP id\n\tf21mr5679714lfh.114.1595618122693; \n\tFri, 24 Jul 2020 12:15:22 -0700 (PDT)","Date":"Fri, 24 Jul 2020 21:15:21 +0200","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20200724191521.GD2729799@oden.dyn.berto.se>","References":"<20200724174827.757493-1-niklas.soderlund@ragnatech.se>\n\t<20200724174827.757493-4-niklas.soderlund@ragnatech.se>\n\t<20200724180059.GZ5921@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200724180059.GZ5921@pendragon.ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v2 3/3] cam: Add optional argument to\n\t--capture to specify how many frames to capture","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>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"iso-8859-1\"","Content-Transfer-Encoding":"quoted-printable","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]