[{"id":510,"web_url":"https://patchwork.libcamera.org/comment/510/","msgid":"<20190123090414.ylzde37xpafjyebn@uno.localdomain>","date":"2019-01-23T09:04:14","subject":"Re: [libcamera-devel] [PATCH 2/3] libcamera: pipelines: keep\n\treference to cameras created","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Niklas,\n\nOn Wed, Jan 23, 2019 at 12:29:54AM +0100, Niklas Söderlund wrote:\n> The pipeline handlers needs to keep a reference to the cameras it\n> creates in order to notify it when it's being disconnected. When\n> hot-unplug support is added the pipeline handler would be deleted when\n> the hardware is removed from under it.\n\nI might have missed a piece here, I understand cameras are subject to\nhot-unplug, and might go away at run time. what is the use case you\nconsidered for removing a pipeline handler at run time?\n\n>\n> After the deletion of pipeline handler all the Camera objects created by\n> the pipeline handler might still be around as they might be in use by a\n> application. At this point the pipeline handler should inform the camera\n> that it's disconnected.\n>\n> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> ---\n>  src/libcamera/pipeline/ipu3/ipu3.cpp |  7 ++++++-\n>  src/libcamera/pipeline/uvcvideo.cpp  | 10 +++++++---\n>  src/libcamera/pipeline/vimc.cpp      | 11 +++++++----\n>  3 files changed, 20 insertions(+), 8 deletions(-)\n>\n> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> index 48d028f7e6cd9b4d..19f73011f8b75438 100644\n> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> @@ -32,6 +32,8 @@ private:\n>  \tMediaDevice *cio2_;\n>  \tMediaDevice *imgu_;\n>\n> +\tstd::vector<std::shared_ptr<Camera>> cameras_;\n> +\n\nInstead of doing this in each pipeline hander, can't this be moved to\nthe base class?\n\n>  \tvoid registerCameras(CameraManager *manager);\n>  };\n>\n> @@ -42,6 +44,8 @@ PipelineHandlerIPU3::PipelineHandlerIPU3()\n>\n>  PipelineHandlerIPU3::~PipelineHandlerIPU3()\n>  {\n> +\tcameras_.clear();\n> +\n>  \tif (cio2_)\n>  \t\tcio2_->release();\n>\n> @@ -173,7 +177,8 @@ void PipelineHandlerIPU3::registerCameras(CameraManager *manager)\n>  \t\tstd::string cameraName = sensor->name() + \" \" + std::to_string(id);\n>  \t\tstd::shared_ptr<Camera> camera = Camera::create(cameraName,\n>  \t\t\t\t\t\t\t\tthis);\n> -\t\tmanager->addCamera(std::move(camera));\n> +\t\tcameras_.push_back(camera);\n\nBe careful, this copies the shared reference, increasing the reference\ncount if I got this right. What's your opinion?\n\n\n> +\t\tmanager->addCamera(camera);\n>\n>  \t\tLOG(IPU3, Info)\n>  \t\t\t<< \"Registered Camera[\" << numCameras << \"] \\\"\"\n> diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp\n> index 3651250b683e7810..2162824eb571fba7 100644\n> --- a/src/libcamera/pipeline/uvcvideo.cpp\n> +++ b/src/libcamera/pipeline/uvcvideo.cpp\n> @@ -24,15 +24,19 @@ public:\n>\n>  private:\n>  \tMediaDevice *dev_;\n> +\tstd::shared_ptr<Camera> camera_;\n\nShouldn't this, and a method to register cameras to the manager should be\nmoved to the base class?\n\nThe base class can provide a \"registerCamera\" method,\nthat takes the camera name and the camera manager. It creates the\ncamera as shared_ptr, move it to the  'camera_' vector, and register\nit with the camera manager (which receives it by value, and move it in\nits own vector too).\n\nWhat do you think? Have you considered it and went for this\nimplementation for some reason I am missing?\n\nThanks\n   j\n\n\n>  };\n>\n>  PipelineHandlerUVC::PipelineHandlerUVC()\n> -\t: dev_(nullptr)\n> +\t: dev_(nullptr), camera_(nullptr)\n>  {\n>  }\n>\n>  PipelineHandlerUVC::~PipelineHandlerUVC()\n>  {\n> +\tif (camera_)\n> +\t\tcamera_ = nullptr;\n> +\n>  \tif (dev_)\n>  \t\tdev_->release();\n>  }\n> @@ -48,8 +52,8 @@ bool PipelineHandlerUVC::match(CameraManager *manager, DeviceEnumerator *enumera\n>\n>  \tdev_->acquire();\n>\n> -\tstd::shared_ptr<Camera> camera = Camera::create(dev_->model(), this);\n> -\tmanager->addCamera(std::move(camera));\n> +\tcamera_ = Camera::create(dev_->model(), this);\n> +\tmanager->addCamera(camera_);\n>\n>  \treturn true;\n>  }\n> diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp\n> index 81d8319eb88e06d2..373fc0ee5339f9ae 100644\n> --- a/src/libcamera/pipeline/vimc.cpp\n> +++ b/src/libcamera/pipeline/vimc.cpp\n> @@ -24,15 +24,19 @@ public:\n>\n>  private:\n>  \tMediaDevice *dev_;\n> +\tstd::shared_ptr<Camera> camera_;\n>  };\n>\n>  PipeHandlerVimc::PipeHandlerVimc()\n> -\t: dev_(nullptr)\n> +\t: dev_(nullptr), camera_(nullptr)\n>  {\n>  }\n>\n>  PipeHandlerVimc::~PipeHandlerVimc()\n>  {\n> +\tif (camera_)\n> +\t\tcamera_ = nullptr;\n> +\n>  \tif (dev_)\n>  \t\tdev_->release();\n>  }\n> @@ -57,9 +61,8 @@ bool PipeHandlerVimc::match(CameraManager *manager, DeviceEnumerator *enumerator\n>\n>  \tdev_->acquire();\n>\n> -\tstd::shared_ptr<Camera> camera = Camera::create(\"Dummy VIMC Camera\",\n> -\t\t\t\t\t\t\tthis);\n> -\tmanager->addCamera(std::move(camera));\n> +\tcamera_ = Camera::create(\"Dummy VIMC Camera\", this);\n> +\tmanager->addCamera(camera_);\n>\n>  \treturn true;\n>  }\n> --\n> 2.20.1\n>\n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","headers":{"Return-Path":"<jacopo@jmondi.org>","Received":["from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net\n\t[217.70.183.201])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 7253560B1B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 23 Jan 2019 10:04:02 +0100 (CET)","from uno.localdomain (unknown [37.177.134.137])\n\t(Authenticated sender: jacopo@jmondi.org)\n\tby relay8-d.mail.gandi.net (Postfix) with ESMTPSA id C92C51BF20D;\n\tWed, 23 Jan 2019 09:04:01 +0000 (UTC)"],"X-Originating-IP":"37.177.134.137","Date":"Wed, 23 Jan 2019 10:04:14 +0100","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Niklas =?utf-8?q?S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20190123090414.ylzde37xpafjyebn@uno.localdomain>","References":"<20190122232955.31783-1-niklas.soderlund@ragnatech.se>\n\t<20190122232955.31783-3-niklas.soderlund@ragnatech.se>","MIME-Version":"1.0","Content-Type":"multipart/signed; micalg=pgp-sha256;\n\tprotocol=\"application/pgp-signature\"; boundary=\"dz2j3d3w2ucpz3tu\"","Content-Disposition":"inline","In-Reply-To":"<20190122232955.31783-3-niklas.soderlund@ragnatech.se>","User-Agent":"NeoMutt/20180716","Subject":"Re: [libcamera-devel] [PATCH 2/3] libcamera: pipelines: keep\n\treference to cameras created","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","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>","X-List-Received-Date":"Wed, 23 Jan 2019 09:04:02 -0000"}},{"id":512,"web_url":"https://patchwork.libcamera.org/comment/512/","msgid":"<20190123093741.GJ4127@bigcity.dyn.berto.se>","date":"2019-01-23T09:37:41","subject":"Re: [libcamera-devel] [PATCH 2/3] libcamera: pipelines: keep\n\treference to cameras created","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Jacopo,\n\nThanks for your feedback.\n\nOn 2019-01-23 10:04:14 +0100, Jacopo Mondi wrote:\n> Hi Niklas,\n> \n> On Wed, Jan 23, 2019 at 12:29:54AM +0100, Niklas Söderlund wrote:\n> > The pipeline handlers needs to keep a reference to the cameras it\n> > creates in order to notify it when it's being disconnected. When\n> > hot-unplug support is added the pipeline handler would be deleted when\n> > the hardware is removed from under it.\n> \n> I might have missed a piece here, I understand cameras are subject to\n> hot-unplug, and might go away at run time. what is the use case you\n> considered for removing a pipeline handler at run time?\n\nMy idea here is that the object of the specific PipelineHandler \nimplementation (e.g. PipelineHandlerIPU3) that is i instantiated to \nsupport a specific hardware is deleted when the hardware it represents \nis deleted due to hot-plug. In this event the pipeline handler that is \ndeleted needs to inform all Camera objects it created that the hardware \nis gone and it will serve no more requests.\n\nSo I'm not taking about removing the ability to create new instances of \na specific PipelineHandler, but rather that a instantiation of one that \nis 'bound' to a hardware block would be deleted if the hardware is \nremoved.\n\nAs we both know a Camera object might live after the hardware is removed \nand needs to be 'disconnected'. That is what happens in the last patch \nin this series and that completes the life-time management of the \nassociation between the Camera and PipelineHandler classes.\n\n> \n> >\n> > After the deletion of pipeline handler all the Camera objects created by\n> > the pipeline handler might still be around as they might be in use by a\n> > application. At this point the pipeline handler should inform the camera\n> > that it's disconnected.\n> >\n> > Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> > ---\n> >  src/libcamera/pipeline/ipu3/ipu3.cpp |  7 ++++++-\n> >  src/libcamera/pipeline/uvcvideo.cpp  | 10 +++++++---\n> >  src/libcamera/pipeline/vimc.cpp      | 11 +++++++----\n> >  3 files changed, 20 insertions(+), 8 deletions(-)\n> >\n> > diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > index 48d028f7e6cd9b4d..19f73011f8b75438 100644\n> > --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > @@ -32,6 +32,8 @@ private:\n> >  \tMediaDevice *cio2_;\n> >  \tMediaDevice *imgu_;\n> >\n> > +\tstd::vector<std::shared_ptr<Camera>> cameras_;\n> > +\n> \n> Instead of doing this in each pipeline hander, can't this be moved to\n> the base class?\n> \n> >  \tvoid registerCameras(CameraManager *manager);\n> >  };\n> >\n> > @@ -42,6 +44,8 @@ PipelineHandlerIPU3::PipelineHandlerIPU3()\n> >\n> >  PipelineHandlerIPU3::~PipelineHandlerIPU3()\n> >  {\n> > +\tcameras_.clear();\n> > +\n> >  \tif (cio2_)\n> >  \t\tcio2_->release();\n> >\n> > @@ -173,7 +177,8 @@ void PipelineHandlerIPU3::registerCameras(CameraManager *manager)\n> >  \t\tstd::string cameraName = sensor->name() + \" \" + std::to_string(id);\n> >  \t\tstd::shared_ptr<Camera> camera = Camera::create(cameraName,\n> >  \t\t\t\t\t\t\t\tthis);\n> > -\t\tmanager->addCamera(std::move(camera));\n> > +\t\tcameras_.push_back(camera);\n> \n> Be careful, this copies the shared reference, increasing the reference\n> count if I got this right. What's your opinion?\n> \n> \n> > +\t\tmanager->addCamera(camera);\n> >\n> >  \t\tLOG(IPU3, Info)\n> >  \t\t\t<< \"Registered Camera[\" << numCameras << \"] \\\"\"\n> > diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp\n> > index 3651250b683e7810..2162824eb571fba7 100644\n> > --- a/src/libcamera/pipeline/uvcvideo.cpp\n> > +++ b/src/libcamera/pipeline/uvcvideo.cpp\n> > @@ -24,15 +24,19 @@ public:\n> >\n> >  private:\n> >  \tMediaDevice *dev_;\n> > +\tstd::shared_ptr<Camera> camera_;\n> \n> Shouldn't this, and a method to register cameras to the manager should be\n> moved to the base class?\n> \n> The base class can provide a \"registerCamera\" method,\n> that takes the camera name and the camera manager. It creates the\n> camera as shared_ptr, move it to the  'camera_' vector, and register\n> it with the camera manager (which receives it by value, and move it in\n> its own vector too).\n> \n> What do you think? Have you considered it and went for this\n> implementation for some reason I am missing?\n\nI have considered it, and I should have outlined this in the cover \nletter. Instead I added it to the cover letter of the series which \ndepends on this series. Sorry about that.\n\nIn essence I think it's a good idea that we should move as much as \npossible to the base classes to remove boiler plate for the specific \nimplementations. I had on my todo list for today to try and improve this \nin this and my other series. Your idea of a registerCamera() in the base \nclass sounds like the way to go so I will start with that, thanks for \nthe suggestion!\n\n> \n> Thanks\n>    j\n> \n> \n> >  };\n> >\n> >  PipelineHandlerUVC::PipelineHandlerUVC()\n> > -\t: dev_(nullptr)\n> > +\t: dev_(nullptr), camera_(nullptr)\n> >  {\n> >  }\n> >\n> >  PipelineHandlerUVC::~PipelineHandlerUVC()\n> >  {\n> > +\tif (camera_)\n> > +\t\tcamera_ = nullptr;\n> > +\n> >  \tif (dev_)\n> >  \t\tdev_->release();\n> >  }\n> > @@ -48,8 +52,8 @@ bool PipelineHandlerUVC::match(CameraManager *manager, DeviceEnumerator *enumera\n> >\n> >  \tdev_->acquire();\n> >\n> > -\tstd::shared_ptr<Camera> camera = Camera::create(dev_->model(), this);\n> > -\tmanager->addCamera(std::move(camera));\n> > +\tcamera_ = Camera::create(dev_->model(), this);\n> > +\tmanager->addCamera(camera_);\n> >\n> >  \treturn true;\n> >  }\n> > diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp\n> > index 81d8319eb88e06d2..373fc0ee5339f9ae 100644\n> > --- a/src/libcamera/pipeline/vimc.cpp\n> > +++ b/src/libcamera/pipeline/vimc.cpp\n> > @@ -24,15 +24,19 @@ public:\n> >\n> >  private:\n> >  \tMediaDevice *dev_;\n> > +\tstd::shared_ptr<Camera> camera_;\n> >  };\n> >\n> >  PipeHandlerVimc::PipeHandlerVimc()\n> > -\t: dev_(nullptr)\n> > +\t: dev_(nullptr), camera_(nullptr)\n> >  {\n> >  }\n> >\n> >  PipeHandlerVimc::~PipeHandlerVimc()\n> >  {\n> > +\tif (camera_)\n> > +\t\tcamera_ = nullptr;\n> > +\n> >  \tif (dev_)\n> >  \t\tdev_->release();\n> >  }\n> > @@ -57,9 +61,8 @@ bool PipeHandlerVimc::match(CameraManager *manager, DeviceEnumerator *enumerator\n> >\n> >  \tdev_->acquire();\n> >\n> > -\tstd::shared_ptr<Camera> camera = Camera::create(\"Dummy VIMC Camera\",\n> > -\t\t\t\t\t\t\tthis);\n> > -\tmanager->addCamera(std::move(camera));\n> > +\tcamera_ = Camera::create(\"Dummy VIMC Camera\", this);\n> > +\tmanager->addCamera(camera_);\n> >\n> >  \treturn true;\n> >  }\n> > --\n> > 2.20.1\n> >\n> > _______________________________________________\n> > libcamera-devel mailing list\n> > libcamera-devel@lists.libcamera.org\n> > https://lists.libcamera.org/listinfo/libcamera-devel","headers":{"Return-Path":"<niklas.soderlund@ragnatech.se>","Received":["from mail-lf1-x12a.google.com (mail-lf1-x12a.google.com\n\t[IPv6:2a00:1450:4864:20::12a])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E60B160B1B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 23 Jan 2019 10:37:42 +0100 (CET)","by mail-lf1-x12a.google.com with SMTP id f5so1040016lfc.13\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 23 Jan 2019 01:37:42 -0800 (PST)","from localhost (89-233-230-99.cust.bredband2.com. [89.233.230.99])\n\tby smtp.gmail.com with ESMTPSA id\n\tm63-v6sm446603lje.81.2019.01.23.01.37.41\n\t(version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);\n\tWed, 23 Jan 2019 01:37:41 -0800 (PST)"],"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\t:user-agent; bh=iPR4HiPVB2TXRxBDrodqrnbabEQMBZqc28ElDTAk9/k=;\n\tb=Xcf0M9ODmgt4vPqIIWk4ZE1uGG6C+7QOikVFOZG+Hf+SsAHYAdxpTa9qam3xxBkxRb\n\t5fn+frmMVf8Q51K1aFxSFzmSeAVPiA2RfoF9yRrbHYfckghx/L0ahpzcKprVT2sqZsSN\n\t240GEw5dJoc/fvT2m28Exxafi3s/C+BDw4dZK+bS4lERqjDE1+KkT6WvFVAssCe/1olE\n\tlDg0pQ54WSh4gp9lgVFee/YUIV3TmjLl7JQ7e0WV3i5Lk3BvCV7KeatIxbsgSaSI1aKd\n\tDWfzpqx/wdfQv+pAW0kdzn+y/ghJ80ltNGft/D9LM0DyYpprYpjfiAmuJQiieaKiqnU5\n\to9KQ==","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:user-agent;\n\tbh=iPR4HiPVB2TXRxBDrodqrnbabEQMBZqc28ElDTAk9/k=;\n\tb=ou94EYnnqcYYQqrKnH1YZaVcA5nXVqaUPsJBkEXeOQXuYQHZr0A1P+myWhvzF3RuHE\n\tmB+Cb8zXl3be77YDjcNPPd8NrPzUIl05gie8K3rTmtDLAac01mYa8Wsohc/H5DuAfx6W\n\thTG4l/IcZogVJd0d20CGQNyqbTl++ynTSWCb0656meJPh4FtnMUZaOW1nVzJsnGPYItV\n\t3Mp9SI96FkWh1Y49LgWZySRHNhQcqpOVdd3lIwm4eIsjE6yRiXvuiHY9RQKkFmnZxkgg\n\tmIoTlSHrx8pkz5cJfRxmq4XqUQTt6ibtTgaEUSPidprY8tkU1hRO9OjiKBBE7raovwOp\n\tqpEg==","X-Gm-Message-State":"AJcUukc3v2JNFLnzg7uTjHw12uF3mGFUplIKXSQYSval/ijQI6Rs7WJ3\n\tlEtkZ7fNFiaGdtsjEEz7kph2Qj03hSo=","X-Google-Smtp-Source":"ALg8bN7ux09fJkdzCL4/CwQJhnnCKUPVcmt8XvqZGwPfkC5ZhpTOp8404/uoA5BXyosUKL+eWU0ctg==","X-Received":"by 2002:a19:2755:: with SMTP id n82mr1240393lfn.94.1548236262116;\n\tWed, 23 Jan 2019 01:37:42 -0800 (PST)","Date":"Wed, 23 Jan 2019 10:37:41 +0100","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Jacopo Mondi <jacopo@jmondi.org>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20190123093741.GJ4127@bigcity.dyn.berto.se>","References":"<20190122232955.31783-1-niklas.soderlund@ragnatech.se>\n\t<20190122232955.31783-3-niklas.soderlund@ragnatech.se>\n\t<20190123090414.ylzde37xpafjyebn@uno.localdomain>","MIME-Version":"1.0","Content-Type":"text/plain; charset=iso-8859-1","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20190123090414.ylzde37xpafjyebn@uno.localdomain>","User-Agent":"Mutt/1.10.1 (2018-07-13)","Subject":"Re: [libcamera-devel] [PATCH 2/3] libcamera: pipelines: keep\n\treference to cameras created","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","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>","X-List-Received-Date":"Wed, 23 Jan 2019 09:37:43 -0000"}},{"id":513,"web_url":"https://patchwork.libcamera.org/comment/513/","msgid":"<20190123095102.johinngyv6xp36bp@uno.localdomain>","date":"2019-01-23T09:51:02","subject":"Re: [libcamera-devel] [PATCH 2/3] libcamera: pipelines: keep\n\treference to cameras created","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Niklas,\n\nOn Wed, Jan 23, 2019 at 10:37:41AM +0100, Niklas Söderlund wrote:\n> Hi Jacopo,\n>\n> Thanks for your feedback.\n>\n> On 2019-01-23 10:04:14 +0100, Jacopo Mondi wrote:\n> > Hi Niklas,\n> >\n> > On Wed, Jan 23, 2019 at 12:29:54AM +0100, Niklas Söderlund wrote:\n> > > The pipeline handlers needs to keep a reference to the cameras it\n> > > creates in order to notify it when it's being disconnected. When\n> > > hot-unplug support is added the pipeline handler would be deleted when\n> > > the hardware is removed from under it.\n> >\n> > I might have missed a piece here, I understand cameras are subject to\n> > hot-unplug, and might go away at run time. what is the use case you\n> > considered for removing a pipeline handler at run time?\n>\n> My idea here is that the object of the specific PipelineHandler\n> implementation (e.g. PipelineHandlerIPU3) that is i instantiated to\n> support a specific hardware is deleted when the hardware it represents\n> is deleted due to hot-plug. In this event the pipeline handler that is\n> deleted needs to inform all Camera objects it created that the hardware\n> is gone and it will serve no more requests.\n\nI see. Thinking about pipeline handler managing ISPs embedded in the\nSoC the only \"removal\" use case is driver unbinding then, while you\nexpect, say, the UVC pipeline handler to be removed once the USB\ncamera is disconnected.\n\nAs I understood this, the DeviceEnumerator should catch those events,\nnotify the pipeline manager that it has to invalidate all cameras (as\nthey might outlive the pipeline handler) and then \"unmatch\" it, which\ninvolves deleting the pipeline handler instance. It seems we're on the\nsame page, right?\n\n>\n> So I'm not taking about removing the ability to create new instances of\n> a specific PipelineHandler, but rather that a instantiation of one that\n\n> is 'bound' to a hardware block would be deleted if the hardware is\n> removed.\n>\n> As we both know a Camera object might live after the hardware is removed\n> and needs to be 'disconnected'. That is what happens in the last patch\n> in this series and that completes the life-time management of the\n> association between the Camera and PipelineHandler classes.\n>\n> >\n> > >\n> > > After the deletion of pipeline handler all the Camera objects created by\n> > > the pipeline handler might still be around as they might be in use by a\n> > > application. At this point the pipeline handler should inform the camera\n> > > that it's disconnected.\n> > >\n> > > Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> > > ---\n> > >  src/libcamera/pipeline/ipu3/ipu3.cpp |  7 ++++++-\n> > >  src/libcamera/pipeline/uvcvideo.cpp  | 10 +++++++---\n> > >  src/libcamera/pipeline/vimc.cpp      | 11 +++++++----\n> > >  3 files changed, 20 insertions(+), 8 deletions(-)\n> > >\n> > > diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > > index 48d028f7e6cd9b4d..19f73011f8b75438 100644\n> > > --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > > +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > > @@ -32,6 +32,8 @@ private:\n> > >  \tMediaDevice *cio2_;\n> > >  \tMediaDevice *imgu_;\n> > >\n> > > +\tstd::vector<std::shared_ptr<Camera>> cameras_;\n> > > +\n> >\n> > Instead of doing this in each pipeline hander, can't this be moved to\n> > the base class?\n> >\n> > >  \tvoid registerCameras(CameraManager *manager);\n> > >  };\n> > >\n> > > @@ -42,6 +44,8 @@ PipelineHandlerIPU3::PipelineHandlerIPU3()\n> > >\n> > >  PipelineHandlerIPU3::~PipelineHandlerIPU3()\n> > >  {\n> > > +\tcameras_.clear();\n> > > +\n> > >  \tif (cio2_)\n> > >  \t\tcio2_->release();\n> > >\n> > > @@ -173,7 +177,8 @@ void PipelineHandlerIPU3::registerCameras(CameraManager *manager)\n> > >  \t\tstd::string cameraName = sensor->name() + \" \" + std::to_string(id);\n> > >  \t\tstd::shared_ptr<Camera> camera = Camera::create(cameraName,\n> > >  \t\t\t\t\t\t\t\tthis);\n> > > -\t\tmanager->addCamera(std::move(camera));\n> > > +\t\tcameras_.push_back(camera);\n> >\n> > Be careful, this copies the shared reference, increasing the reference\n> > count if I got this right. What's your opinion?\n> >\n> >\n> > > +\t\tmanager->addCamera(camera);\n> > >\n> > >  \t\tLOG(IPU3, Info)\n> > >  \t\t\t<< \"Registered Camera[\" << numCameras << \"] \\\"\"\n> > > diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp\n> > > index 3651250b683e7810..2162824eb571fba7 100644\n> > > --- a/src/libcamera/pipeline/uvcvideo.cpp\n> > > +++ b/src/libcamera/pipeline/uvcvideo.cpp\n> > > @@ -24,15 +24,19 @@ public:\n> > >\n> > >  private:\n> > >  \tMediaDevice *dev_;\n> > > +\tstd::shared_ptr<Camera> camera_;\n> >\n> > Shouldn't this, and a method to register cameras to the manager should be\n> > moved to the base class?\n> >\n> > The base class can provide a \"registerCamera\" method,\n> > that takes the camera name and the camera manager. It creates the\n> > camera as shared_ptr, move it to the  'camera_' vector, and register\n> > it with the camera manager (which receives it by value, and move it in\n> > its own vector too).\n> >\n> > What do you think? Have you considered it and went for this\n> > implementation for some reason I am missing?\n>\n> I have considered it, and I should have outlined this in the cover\n> letter. Instead I added it to the cover letter of the series which\n> depends on this series. Sorry about that.\n>\n> In essence I think it's a good idea that we should move as much as\n> possible to the base classes to remove boiler plate for the specific\n> implementations. I had on my todo list for today to try and improve this\n> in this and my other series. Your idea of a registerCamera() in the base\n> class sounds like the way to go so I will start with that, thanks for\n> the suggestion!\n>\n> >\n> > Thanks\n> >    j\n> >\n> >\n> > >  };\n> > >\n> > >  PipelineHandlerUVC::PipelineHandlerUVC()\n> > > -\t: dev_(nullptr)\n> > > +\t: dev_(nullptr), camera_(nullptr)\n> > >  {\n> > >  }\n> > >\n> > >  PipelineHandlerUVC::~PipelineHandlerUVC()\n> > >  {\n> > > +\tif (camera_)\n> > > +\t\tcamera_ = nullptr;\n> > > +\n> > >  \tif (dev_)\n> > >  \t\tdev_->release();\n> > >  }\n> > > @@ -48,8 +52,8 @@ bool PipelineHandlerUVC::match(CameraManager *manager, DeviceEnumerator *enumera\n> > >\n> > >  \tdev_->acquire();\n> > >\n> > > -\tstd::shared_ptr<Camera> camera = Camera::create(dev_->model(), this);\n> > > -\tmanager->addCamera(std::move(camera));\n> > > +\tcamera_ = Camera::create(dev_->model(), this);\n> > > +\tmanager->addCamera(camera_);\n> > >\n> > >  \treturn true;\n> > >  }\n> > > diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp\n> > > index 81d8319eb88e06d2..373fc0ee5339f9ae 100644\n> > > --- a/src/libcamera/pipeline/vimc.cpp\n> > > +++ b/src/libcamera/pipeline/vimc.cpp\n> > > @@ -24,15 +24,19 @@ public:\n> > >\n> > >  private:\n> > >  \tMediaDevice *dev_;\n> > > +\tstd::shared_ptr<Camera> camera_;\n> > >  };\n> > >\n> > >  PipeHandlerVimc::PipeHandlerVimc()\n> > > -\t: dev_(nullptr)\n> > > +\t: dev_(nullptr), camera_(nullptr)\n> > >  {\n> > >  }\n> > >\n> > >  PipeHandlerVimc::~PipeHandlerVimc()\n> > >  {\n> > > +\tif (camera_)\n> > > +\t\tcamera_ = nullptr;\n> > > +\n> > >  \tif (dev_)\n> > >  \t\tdev_->release();\n> > >  }\n> > > @@ -57,9 +61,8 @@ bool PipeHandlerVimc::match(CameraManager *manager, DeviceEnumerator *enumerator\n> > >\n> > >  \tdev_->acquire();\n> > >\n> > > -\tstd::shared_ptr<Camera> camera = Camera::create(\"Dummy VIMC Camera\",\n> > > -\t\t\t\t\t\t\tthis);\n> > > -\tmanager->addCamera(std::move(camera));\n> > > +\tcamera_ = Camera::create(\"Dummy VIMC Camera\", this);\n> > > +\tmanager->addCamera(camera_);\n> > >\n> > >  \treturn true;\n> > >  }\n> > > --\n> > > 2.20.1\n> > >\n> > > _______________________________________________\n> > > libcamera-devel mailing list\n> > > libcamera-devel@lists.libcamera.org\n> > > https://lists.libcamera.org/listinfo/libcamera-devel\n>\n>\n>\n> --\n> Regards,\n> Niklas Söderlund","headers":{"Return-Path":"<jacopo@jmondi.org>","Received":["from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net\n\t[217.70.183.200])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D96D560B1B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 23 Jan 2019 10:50:49 +0100 (CET)","from uno.localdomain (unknown [37.177.134.137])\n\t(Authenticated sender: jacopo@jmondi.org)\n\tby relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 4A4C22000A;\n\tWed, 23 Jan 2019 09:50:49 +0000 (UTC)"],"X-Originating-IP":"37.177.134.137","Date":"Wed, 23 Jan 2019 10:51:02 +0100","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Niklas =?utf-8?q?S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20190123095102.johinngyv6xp36bp@uno.localdomain>","References":"<20190122232955.31783-1-niklas.soderlund@ragnatech.se>\n\t<20190122232955.31783-3-niklas.soderlund@ragnatech.se>\n\t<20190123090414.ylzde37xpafjyebn@uno.localdomain>\n\t<20190123093741.GJ4127@bigcity.dyn.berto.se>","MIME-Version":"1.0","Content-Type":"multipart/signed; micalg=pgp-sha256;\n\tprotocol=\"application/pgp-signature\"; boundary=\"6z6k7oysljc4ogjl\"","Content-Disposition":"inline","In-Reply-To":"<20190123093741.GJ4127@bigcity.dyn.berto.se>","User-Agent":"NeoMutt/20180716","Subject":"Re: [libcamera-devel] [PATCH 2/3] libcamera: pipelines: keep\n\treference to cameras created","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","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>","X-List-Received-Date":"Wed, 23 Jan 2019 09:50:50 -0000"}},{"id":516,"web_url":"https://patchwork.libcamera.org/comment/516/","msgid":"<20190123102408.GL4127@bigcity.dyn.berto.se>","date":"2019-01-23T10:24:08","subject":"Re: [libcamera-devel] [PATCH 2/3] libcamera: pipelines: keep\n\treference to cameras created","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Jacopo,\n\nOn 2019-01-23 10:51:02 +0100, Jacopo Mondi wrote:\n> Hi Niklas,\n> \n> On Wed, Jan 23, 2019 at 10:37:41AM +0100, Niklas Söderlund wrote:\n> > Hi Jacopo,\n> >\n> > Thanks for your feedback.\n> >\n> > On 2019-01-23 10:04:14 +0100, Jacopo Mondi wrote:\n> > > Hi Niklas,\n> > >\n> > > On Wed, Jan 23, 2019 at 12:29:54AM +0100, Niklas Söderlund wrote:\n> > > > The pipeline handlers needs to keep a reference to the cameras it\n> > > > creates in order to notify it when it's being disconnected. When\n> > > > hot-unplug support is added the pipeline handler would be deleted when\n> > > > the hardware is removed from under it.\n> > >\n> > > I might have missed a piece here, I understand cameras are subject to\n> > > hot-unplug, and might go away at run time. what is the use case you\n> > > considered for removing a pipeline handler at run time?\n> >\n> > My idea here is that the object of the specific PipelineHandler\n> > implementation (e.g. PipelineHandlerIPU3) that is i instantiated to\n> > support a specific hardware is deleted when the hardware it represents\n> > is deleted due to hot-plug. In this event the pipeline handler that is\n> > deleted needs to inform all Camera objects it created that the hardware\n> > is gone and it will serve no more requests.\n> \n> I see. Thinking about pipeline handler managing ISPs embedded in the\n> SoC the only \"removal\" use case is driver unbinding then, while you\n> expect, say, the UVC pipeline handler to be removed once the USB\n> camera is disconnected.\n> \n> As I understood this, the DeviceEnumerator should catch those events,\n> notify the pipeline manager that it has to invalidate all cameras (as\n> they might outlive the pipeline handler) and then \"unmatch\" it, which\n> involves deleting the pipeline handler instance. It seems we're on the\n> same page, right?\n\nYes it seems so :-)\n\nIn the current design the DeviceEnumerator would simply delete the \npipeline handler when it detects that the hardware is being removed. How \nit will know which pipeline to delete, and how to react to one entity in \na media graph and related issue is still not known.\n\n> \n> >\n> > So I'm not taking about removing the ability to create new instances of\n> > a specific PipelineHandler, but rather that a instantiation of one that\n> \n> > is 'bound' to a hardware block would be deleted if the hardware is\n> > removed.\n> >\n> > As we both know a Camera object might live after the hardware is removed\n> > and needs to be 'disconnected'. That is what happens in the last patch\n> > in this series and that completes the life-time management of the\n> > association between the Camera and PipelineHandler classes.\n> >\n> > >\n> > > >\n> > > > After the deletion of pipeline handler all the Camera objects created by\n> > > > the pipeline handler might still be around as they might be in use by a\n> > > > application. At this point the pipeline handler should inform the camera\n> > > > that it's disconnected.\n> > > >\n> > > > Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> > > > ---\n> > > >  src/libcamera/pipeline/ipu3/ipu3.cpp |  7 ++++++-\n> > > >  src/libcamera/pipeline/uvcvideo.cpp  | 10 +++++++---\n> > > >  src/libcamera/pipeline/vimc.cpp      | 11 +++++++----\n> > > >  3 files changed, 20 insertions(+), 8 deletions(-)\n> > > >\n> > > > diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > > > index 48d028f7e6cd9b4d..19f73011f8b75438 100644\n> > > > --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > > > +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > > > @@ -32,6 +32,8 @@ private:\n> > > >  \tMediaDevice *cio2_;\n> > > >  \tMediaDevice *imgu_;\n> > > >\n> > > > +\tstd::vector<std::shared_ptr<Camera>> cameras_;\n> > > > +\n> > >\n> > > Instead of doing this in each pipeline hander, can't this be moved to\n> > > the base class?\n> > >\n> > > >  \tvoid registerCameras(CameraManager *manager);\n> > > >  };\n> > > >\n> > > > @@ -42,6 +44,8 @@ PipelineHandlerIPU3::PipelineHandlerIPU3()\n> > > >\n> > > >  PipelineHandlerIPU3::~PipelineHandlerIPU3()\n> > > >  {\n> > > > +\tcameras_.clear();\n> > > > +\n> > > >  \tif (cio2_)\n> > > >  \t\tcio2_->release();\n> > > >\n> > > > @@ -173,7 +177,8 @@ void PipelineHandlerIPU3::registerCameras(CameraManager *manager)\n> > > >  \t\tstd::string cameraName = sensor->name() + \" \" + std::to_string(id);\n> > > >  \t\tstd::shared_ptr<Camera> camera = Camera::create(cameraName,\n> > > >  \t\t\t\t\t\t\t\tthis);\n> > > > -\t\tmanager->addCamera(std::move(camera));\n> > > > +\t\tcameras_.push_back(camera);\n> > >\n> > > Be careful, this copies the shared reference, increasing the reference\n> > > count if I got this right. What's your opinion?\n> > >\n> > >\n> > > > +\t\tmanager->addCamera(camera);\n> > > >\n> > > >  \t\tLOG(IPU3, Info)\n> > > >  \t\t\t<< \"Registered Camera[\" << numCameras << \"] \\\"\"\n> > > > diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp\n> > > > index 3651250b683e7810..2162824eb571fba7 100644\n> > > > --- a/src/libcamera/pipeline/uvcvideo.cpp\n> > > > +++ b/src/libcamera/pipeline/uvcvideo.cpp\n> > > > @@ -24,15 +24,19 @@ public:\n> > > >\n> > > >  private:\n> > > >  \tMediaDevice *dev_;\n> > > > +\tstd::shared_ptr<Camera> camera_;\n> > >\n> > > Shouldn't this, and a method to register cameras to the manager should be\n> > > moved to the base class?\n> > >\n> > > The base class can provide a \"registerCamera\" method,\n> > > that takes the camera name and the camera manager. It creates the\n> > > camera as shared_ptr, move it to the  'camera_' vector, and register\n> > > it with the camera manager (which receives it by value, and move it in\n> > > its own vector too).\n> > >\n> > > What do you think? Have you considered it and went for this\n> > > implementation for some reason I am missing?\n> >\n> > I have considered it, and I should have outlined this in the cover\n> > letter. Instead I added it to the cover letter of the series which\n> > depends on this series. Sorry about that.\n> >\n> > In essence I think it's a good idea that we should move as much as\n> > possible to the base classes to remove boiler plate for the specific\n> > implementations. I had on my todo list for today to try and improve this\n> > in this and my other series. Your idea of a registerCamera() in the base\n> > class sounds like the way to go so I will start with that, thanks for\n> > the suggestion!\n> >\n> > >\n> > > Thanks\n> > >    j\n> > >\n> > >\n> > > >  };\n> > > >\n> > > >  PipelineHandlerUVC::PipelineHandlerUVC()\n> > > > -\t: dev_(nullptr)\n> > > > +\t: dev_(nullptr), camera_(nullptr)\n> > > >  {\n> > > >  }\n> > > >\n> > > >  PipelineHandlerUVC::~PipelineHandlerUVC()\n> > > >  {\n> > > > +\tif (camera_)\n> > > > +\t\tcamera_ = nullptr;\n> > > > +\n> > > >  \tif (dev_)\n> > > >  \t\tdev_->release();\n> > > >  }\n> > > > @@ -48,8 +52,8 @@ bool PipelineHandlerUVC::match(CameraManager *manager, DeviceEnumerator *enumera\n> > > >\n> > > >  \tdev_->acquire();\n> > > >\n> > > > -\tstd::shared_ptr<Camera> camera = Camera::create(dev_->model(), this);\n> > > > -\tmanager->addCamera(std::move(camera));\n> > > > +\tcamera_ = Camera::create(dev_->model(), this);\n> > > > +\tmanager->addCamera(camera_);\n> > > >\n> > > >  \treturn true;\n> > > >  }\n> > > > diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp\n> > > > index 81d8319eb88e06d2..373fc0ee5339f9ae 100644\n> > > > --- a/src/libcamera/pipeline/vimc.cpp\n> > > > +++ b/src/libcamera/pipeline/vimc.cpp\n> > > > @@ -24,15 +24,19 @@ public:\n> > > >\n> > > >  private:\n> > > >  \tMediaDevice *dev_;\n> > > > +\tstd::shared_ptr<Camera> camera_;\n> > > >  };\n> > > >\n> > > >  PipeHandlerVimc::PipeHandlerVimc()\n> > > > -\t: dev_(nullptr)\n> > > > +\t: dev_(nullptr), camera_(nullptr)\n> > > >  {\n> > > >  }\n> > > >\n> > > >  PipeHandlerVimc::~PipeHandlerVimc()\n> > > >  {\n> > > > +\tif (camera_)\n> > > > +\t\tcamera_ = nullptr;\n> > > > +\n> > > >  \tif (dev_)\n> > > >  \t\tdev_->release();\n> > > >  }\n> > > > @@ -57,9 +61,8 @@ bool PipeHandlerVimc::match(CameraManager *manager, DeviceEnumerator *enumerator\n> > > >\n> > > >  \tdev_->acquire();\n> > > >\n> > > > -\tstd::shared_ptr<Camera> camera = Camera::create(\"Dummy VIMC Camera\",\n> > > > -\t\t\t\t\t\t\tthis);\n> > > > -\tmanager->addCamera(std::move(camera));\n> > > > +\tcamera_ = Camera::create(\"Dummy VIMC Camera\", this);\n> > > > +\tmanager->addCamera(camera_);\n> > > >\n> > > >  \treturn true;\n> > > >  }\n> > > > --\n> > > > 2.20.1\n> > > >\n> > > > _______________________________________________\n> > > > libcamera-devel mailing list\n> > > > libcamera-devel@lists.libcamera.org\n> > > > https://lists.libcamera.org/listinfo/libcamera-devel\n> >\n> >\n> >\n> > --\n> > Regards,\n> > Niklas Söderlund","headers":{"Return-Path":"<niklas.soderlund@ragnatech.se>","Received":["from mail-lj1-x233.google.com (mail-lj1-x233.google.com\n\t[IPv6:2a00:1450:4864:20::233])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 904F060B1B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 23 Jan 2019 11:24:10 +0100 (CET)","by mail-lj1-x233.google.com with SMTP id l15-v6so1415327lja.9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 23 Jan 2019 02:24:10 -0800 (PST)","from localhost (89-233-230-99.cust.bredband2.com. [89.233.230.99])\n\tby smtp.gmail.com with ESMTPSA id\n\tm1sm407714lfb.56.2019.01.23.02.24.08\n\t(version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);\n\tWed, 23 Jan 2019 02:24:09 -0800 (PST)"],"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\t:user-agent; bh=wglAaHwkFNWQx+PnHao8t/MYc09f7mBbZvA5R9hVlzA=;\n\tb=queAUEh1ZtnBzmwCMzIId1luEhO6j2eudMstOumfbJycQUxkn2G2oTGIxH3/JmdCdb\n\tn++yHVV7IP52TWPmQEM+K4R9zX9nwB9Gy4+D16I/2UNKKGyDgmLxccfyYrahj4jXzt2/\n\tKXeBfnSQ4G7UitPuabnBtOP+sfrO8gY7h6sNNkfIi9SyAIYTeS2wRayfGHI6Cuhfca1V\n\tzkVyz9V/b5EVFoXyzjs6RYXgNs8uVSxnTLqk8DDa0tFpaqHlA/vYCAZHOAkv6+ei5Kim\n\t81HiP5G95OBmTv7iMBQOqTuc7Err6NXT5+6/sHGaI+VIuh3jVeOgDZrZYwtsqkM/RGfA\n\tCzNA==","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:user-agent;\n\tbh=wglAaHwkFNWQx+PnHao8t/MYc09f7mBbZvA5R9hVlzA=;\n\tb=Hnzc1hkkAVf6+mQq6IcfNnJJ9BHk/cBD88PouoJark78N7SGrhBR01u4+ATb33osln\n\tpMRyDceeZoy6pzTKs1PasdwPj8vjkmp6DslgnWJ2bbdhlWYEEFEBBMJGrzkBQZuvSkC0\n\tJDSbpWRXoJUNoOW6gcWoLYoIKTGpXCRFPuD7pL6m1EnQQyg7OQQBOfbDB6b6jJudAS/A\n\tUcmKm4kVZMnUXDt28IDgBUcHbN1e3aciKS+lLj/LcuqDgenHB3lqAi7nH0hnv9IDV3hz\n\tdcL0d0iTmLbFs3AIK6HrTpYLH5XIH1QCO5eGDkb+oxCTBWFZaQ2Jcm3kPezd35LZIhZ3\n\tkINw==","X-Gm-Message-State":"AJcUukf/xRXxZbsunUxDtHfUM3V5m/mC5yLdn+cLRG8GiwyEARnhP/cv\n\tmRzwJ64mgC4Aer7QpOeW7dkrrg==","X-Google-Smtp-Source":"ALg8bN6xWBRRTQWHtGh0A57ShZ8JOVB8wAyyVOeH2FO8Y6T6z/0kIMhN/4q2zqmnJmZBEZPmwyFLtw==","X-Received":"by 2002:a2e:6e10:: with SMTP id\n\tj16-v6mr1470193ljc.84.1548239049712; \n\tWed, 23 Jan 2019 02:24:09 -0800 (PST)","Date":"Wed, 23 Jan 2019 11:24:08 +0100","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Jacopo Mondi <jacopo@jmondi.org>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20190123102408.GL4127@bigcity.dyn.berto.se>","References":"<20190122232955.31783-1-niklas.soderlund@ragnatech.se>\n\t<20190122232955.31783-3-niklas.soderlund@ragnatech.se>\n\t<20190123090414.ylzde37xpafjyebn@uno.localdomain>\n\t<20190123093741.GJ4127@bigcity.dyn.berto.se>\n\t<20190123095102.johinngyv6xp36bp@uno.localdomain>","MIME-Version":"1.0","Content-Type":"text/plain; charset=iso-8859-1","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20190123095102.johinngyv6xp36bp@uno.localdomain>","User-Agent":"Mutt/1.10.1 (2018-07-13)","Subject":"Re: [libcamera-devel] [PATCH 2/3] libcamera: pipelines: keep\n\treference to cameras created","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","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>","X-List-Received-Date":"Wed, 23 Jan 2019 10:24:10 -0000"}}]