[{"id":3169,"web_url":"https://patchwork.libcamera.org/comment/3169/","msgid":"<20191202121929.37xt4sddcsokc7lz@uno.localdomain>","date":"2019-12-02T12:19:29","subject":"Re: [libcamera-devel] [PATCH 22/30] libcamera: v4l2_videodevice:\n\tAdd V4L2Stream to facilitate buffers","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Niklas,\n\nOn Wed, Nov 27, 2019 at 12:36:12AM +0100, Niklas Söderlund wrote:\n> In the FrameBuffer interface the streams and not the pipelines abstracts\n> the knowledge about how and if buffers needs to be allocated or prepared\n> before a capture session is started.\n>\n> The rational behind this model is the V4L2 API where if applications\n> needs to allocate memory for buffers it do that using a video node and\n\napplications -> \"it do\" ?\n\n> not using a external allocator. As the video node needs to be prepared\n> in different ways depending on if it have been used for memory\n\ns/on if/if\nit have/it has\n\n> allocation or not each streams facing applications needs not only be\n> available to be used to allocated buffers but track if they have been so\n> in order to be started correctly.\n\nvery confusing\n\nAs the video device node needs to be configured to work with memory\nbuffers allocated internally or externally the Stream class needs to\ntrack the current memory usage in order to be properly started.\n\nI'm not even sure that's what you meant.\n\n>\n> This change implements the interface for cameras backed by V4L2 video\n> devices to function with the FrameBuffer interface.\n>\n> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> ---\n>  src/libcamera/include/v4l2_videodevice.h | 24 +++++++\n>  src/libcamera/v4l2_videodevice.cpp       | 90 ++++++++++++++++++++++++\n>  2 files changed, 114 insertions(+)\n>\n> diff --git a/src/libcamera/include/v4l2_videodevice.h b/src/libcamera/include/v4l2_videodevice.h\n> index f4cbcfbd26ea540c..0e94c3f71d0b1208 100644\n> --- a/src/libcamera/include/v4l2_videodevice.h\n> +++ b/src/libcamera/include/v4l2_videodevice.h\n> @@ -16,6 +16,7 @@\n>  #include <libcamera/geometry.h>\n>  #include <libcamera/pixelformats.h>\n>  #include <libcamera/signal.h>\n> +#include <libcamera/stream.h>\n>\n>  #include \"formats.h\"\n>  #include \"log.h\"\n> @@ -236,6 +237,29 @@ private:\n>  \tV4L2VideoDevice *capture_;\n>  };\n>\n> +class V4L2Stream : public Stream\n> +{\n> +public:\n> +\tV4L2Stream(V4L2VideoDevice *video);\n> +\n> +protected:\n> +\tint allocateBuffers(const StreamConfiguration &config,\n> +\t\t\t    std::vector<FrameBuffer *> *buffers) override;\n> +\tvoid releaseBuffers() override;\n> +\tint start() override;\n> +\tvoid stop() override;\n> +\n> +private:\n> +\tenum BufferType {\n> +\t\tNoBuffers,\n> +\t\tAllocatedBuffers,\n> +\t\tExternalBuffers,\n\nthe duality between interanlly and externally allocated buffers is so\nclear that I'm not sure why Allocated/External has to be used here\n\ns/Allocated/Internal\n\nI would drop Buffers completely, as the enum is calle BufferType.\n\n> +\t};\n> +\n> +\tV4L2VideoDevice *video_;\n> +\tBufferType bufferType_;\n> +};\n> +\n>  } /* namespace libcamera */\n>\n>  #endif /* __LIBCAMERA_V4L2_VIDEODEVICE_H__ */\n> diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp\n> index 9fe66018ec502626..f5810956b2040ce6 100644\n> --- a/src/libcamera/v4l2_videodevice.cpp\n> +++ b/src/libcamera/v4l2_videodevice.cpp\n> @@ -1711,4 +1711,94 @@ void V4L2M2MDevice::close()\n>  \toutput_->close();\n>  }\n>\n> +/**\n> + * \\class V4L2Stream\n> + * \\brief V4L2 Video stream for a camera\n\nA stream generated from a V4L2 device ?\n\n> + *\n> + * The V4l2Stream implemets the interfaces mandated by Stream to allow buffers\n\ns/implemets/implements/\ns/mandated/defined/\nby Stream/in the Stream class/\n\n> + * to be allocoated from a video device and presented to the user as if they\n\ns/allocoated/allocated\n\n> + * where allocated externaly.\n\nI understand the \"treat all streams as externally allocated\" is the\njuice of the series, but I'm not sure this is the right place to\nspecify so\n\n> + */\n> +\n> +/**\n> + * \\brief Create a stream around a V4L2 video device\n\naround ? Maybe \"backed by\" ? \"from\" ?\n\n> + * \\param[in] video V4L2 video device to serve\n\nThe V4L2 video device that produces data for the stream ?\n\n> + *\n> + * Create a stream which will manage the application visible buffers for a V4L2\n> + * video device.\n> + */\n> +V4L2Stream::V4L2Stream(V4L2VideoDevice *video)\n> +\t: Stream(), video_(video), bufferType_(NoBuffers)\n> +{\n> +}\n> +\n> +int V4L2Stream::allocateBuffers(const StreamConfiguration &config,\n> +\t\t\t\tstd::vector<FrameBuffer *> *buffers)\n> +{\n> +\tif (bufferType_ != NoBuffers)\n> +\t\treturn -EINVAL;\n> +\n> +\tif (!buffers)\n\n&& !buffers.size()\n\n> +\t\treturn -EINVAL;\n> +\n> +\t/*\n> +\t * \\todo: Extend V4L2VideoDevice to support VIDIOC_CREATE_BUFS which\n> +\t * can take the whole configuration into account, until then use as\n> +\t * much as possible (number of buffers) with VIDIOC_QUERYBUF.\n> +\t *\n> +\t * For this reason check that the format of the video device is the\n> +\t * same as the one request or fail. This will allow for a applicaiton\n\ns/applicaiton/application\n\n> +\t * facing API that will work with VIDIOC_CREATE_BUFS.\n> +\t */\n> +\tV4L2DeviceFormat format;\n> +\tint ret = video_->getFormat(&format);\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n> +\tif (config.size != format.size ||\n> +\t    config.pixelFormat != V4L2VideoDevice::toPixelFormat(format.fourcc))\n> +\t\treturn -EINVAL;\n> +\n> +\tret = video_->allocateBuffers(config.bufferCount, buffers);\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n> +\tbufferType_ = AllocatedBuffers;\n> +\n> +\treturn ret;\n> +}\n> +\n> +void V4L2Stream::releaseBuffers()\n> +{\n> +\tif (bufferType_ == NoBuffers)\n> +\t\treturn;\n> +\n> +\tvideo_->releaseBuffers();\n> +\tbufferType_ = NoBuffers;\n> +}\n> +\n> +int V4L2Stream::start()\n> +{\n> +\t/* If internal buffers is already allocated nothing to do. */\n> +\tif (bufferType_ == AllocatedBuffers)\n> +\t\treturn 0;\n> +\n> +\tint ret = video_->externalBuffers(configuration_.bufferCount);\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n> +\tbufferType_ = ExternalBuffers;\n> +\n> +\treturn ret;\n> +}\n> +\n> +void V4L2Stream::stop()\n> +{\n> +\t/* Only need to clean up if external buffers is used. */\n> +\tif (bufferType_ != ExternalBuffers)\n\nAren't internally allocated buffers that needs to be released?\n\n> +\t\treturn;\n> +\n> +\treleaseBuffers();\n> +}\n> +\n>  } /* namespace libcamera */\n> --\n> 2.24.0\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 relay10.mail.gandi.net (relay10.mail.gandi.net\n\t[217.70.178.230])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CE19160BC4\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  2 Dec 2019 13:17:20 +0100 (CET)","from uno.localdomain (93-34-114-233.ip49.fastwebnet.it\n\t[93.34.114.233]) (Authenticated sender: jacopo@jmondi.org)\n\tby relay10.mail.gandi.net (Postfix) with ESMTPSA id 4E8BC24000A;\n\tMon,  2 Dec 2019 12:17:20 +0000 (UTC)"],"Date":"Mon, 2 Dec 2019 13:19:29 +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":"<20191202121929.37xt4sddcsokc7lz@uno.localdomain>","References":"<20191126233620.1695316-1-niklas.soderlund@ragnatech.se>\n\t<20191126233620.1695316-23-niklas.soderlund@ragnatech.se>","MIME-Version":"1.0","Content-Type":"multipart/signed; micalg=pgp-sha256;\n\tprotocol=\"application/pgp-signature\"; boundary=\"sd5jasciq2f7voff\"","Content-Disposition":"inline","In-Reply-To":"<20191126233620.1695316-23-niklas.soderlund@ragnatech.se>","User-Agent":"NeoMutt/20180716","Subject":"Re: [libcamera-devel] [PATCH 22/30] libcamera: v4l2_videodevice:\n\tAdd V4L2Stream to facilitate buffers","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>","X-List-Received-Date":"Mon, 02 Dec 2019 12:17:21 -0000"}}]