From patchwork Wed Feb 13 15:10:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 570 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BF37A610B3 for ; Wed, 13 Feb 2019 16:10:32 +0100 (CET) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 44A6E304; Wed, 13 Feb 2019 16:10:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1550070632; bh=JDJkQKVftxyHKXfzTyUZcfrR0M385BwFp4tQhRu6w+o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jLevdvJnVCX+6zFiTkPAJOM3UbaY9N/zQERORRyKX/E1BP/PcN9VSnVsjSghkzf/Z pvTI1Lzfybl/b86wyee0L+RO92K+Opvmgquh2u/stzj6NVf3ZlDdGKvDp6C8nUUU2l bx1ZSFKf8PTJQxBLTCN9mbdnT8v87YDnFLCCVkKg= From: Kieran Bingham To: LibCamera Devel Date: Wed, 13 Feb 2019 15:10:20 +0000 Message-Id: <20190213151027.6376-2-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190213151027.6376-1-kieran.bingham@ideasonboard.com> References: <20190213151027.6376-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 1/8] test: v4l2_device: Use VIVID capture stream X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Feb 2019 15:10:32 -0000 Utilise the VIVID capture device for testing the V4L2Device objects. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- test/v4l2_device/v4l2_device_test.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/v4l2_device/v4l2_device_test.cpp b/test/v4l2_device/v4l2_device_test.cpp index 18d014caf4c8..a2a7ba82612d 100644 --- a/test/v4l2_device/v4l2_device_test.cpp +++ b/test/v4l2_device/v4l2_device_test.cpp @@ -39,22 +39,22 @@ int V4L2DeviceTest::init() return TestFail; } - DeviceMatch dm("uvcvideo"); - media_ = std::move(enumerator_->search(dm)); + DeviceMatch dm("vivid"); + dm.add("vivid-000-vid-cap"); + + media_ = enumerator_->search(dm); if (!media_) return TestSkip; media_->acquire(); - for (MediaEntity *entity : media_->entities()) { - if (entity->flags() & MEDIA_ENT_FL_DEFAULT) { - dev_ = new V4L2Device(entity); - break; - } - } + MediaEntity *entity = media_->getEntityByName("vivid-000-vid-cap"); + if (!entity) + return TestSkip; + dev_ = new V4L2Device(entity); if (!dev_) - return TestSkip; + return TestFail; return dev_->open(); } From patchwork Wed Feb 13 15:10:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 571 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EEBE4610B3 for ; Wed, 13 Feb 2019 16:10:32 +0100 (CET) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 8D1F05B6; Wed, 13 Feb 2019 16:10:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1550070632; bh=aoOnnBwJExV51TCGu4TDrq/+OLyuJQhG47PaE6OlYDk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=K1CV7nQmm4sHKQXYKkaxkxnLE2Pg/XQ+sT+qfDanQuruXb10BfNKyLvqhKA+qnS2x INmpJJ9i/gsyxSV+5/hseQ1r5yQRPY8gWJpKXyGfRldLw3lPYXACzPFD0ZvSAd8jF7 ew87DzbqRyXsfh6JOJuNnColEFTm0QUru7X5x4JE= From: Kieran Bingham To: LibCamera Devel Date: Wed, 13 Feb 2019 15:10:21 +0000 Message-Id: <20190213151027.6376-3-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190213151027.6376-1-kieran.bingham@ideasonboard.com> References: <20190213151027.6376-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/8] test: v4l2_device: capture_async: End test at 30 frames X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Feb 2019 15:10:33 -0000 The capture_async test was written to run for a fixed 5 second duration. Modify the test such that it runs until it has captured 30 frames, or a 10 second time out occurs. Running the capture_async test on an ARM64 platform using VIVID captures 30 frames in 6.15 seconds. There may be scope to optimise this speed by changing the format on the capture device. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- test/v4l2_device/capture_async.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/v4l2_device/capture_async.cpp b/test/v4l2_device/capture_async.cpp index 7a0735f65535..ba37c9731831 100644 --- a/test/v4l2_device/capture_async.cpp +++ b/test/v4l2_device/capture_async.cpp @@ -56,9 +56,12 @@ protected: if (ret) return TestFail; - timeout.start(5000); - while (timeout.isRunning()) + timeout.start(10000); + while (timeout.isRunning()) { dispatcher->processEvents(); + if (frames > 30) + break; + } if (frames < 1) { std::cout << "Failed to capture any frames within timeout." << std::endl; From patchwork Wed Feb 13 15:10:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 572 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 40050610B3 for ; Wed, 13 Feb 2019 16:10:33 +0100 (CET) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D5B2C9A5; Wed, 13 Feb 2019 16:10:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1550070633; bh=82pPgT7VeMS1QMd0DnOjk6Y3MuE2k9tcwpUCTpCPNxo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YOIg8bDoVBxtczGmqWqMqaOSKOSno2Sw9TireaxzVk9lfd8hwCOaKBsLAsYxhQOvB Z4asZ4qYekkaQ5QAaxaVF2x0YBYT1OJwcUW7uDB4u9koncd1DsXCTQId+YmKeR/eFB lOYuG5QgVrGlB+/M9OjohMm+NA7Tw+cJkZf2ZPNQ= From: Kieran Bingham To: LibCamera Devel Date: Wed, 13 Feb 2019 15:10:22 +0000 Message-Id: <20190213151027.6376-4-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190213151027.6376-1-kieran.bingham@ideasonboard.com> References: <20190213151027.6376-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 3/8] libcamera: v4l2_device: streamOff() when releasing buffers X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Feb 2019 15:10:33 -0000 We must ensure that the stream is disabled before releasing buffers. It will not hurt to call streamOff() even if it is already off before releasing any buffers back to the device. Signed-off-by: Kieran Bingham --- src/libcamera/v4l2_device.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 23c0da295905..83073c28b817 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -642,6 +642,8 @@ int V4L2Device::releaseBuffers() { LOG(V4L2, Debug) << "Releasing bufferPool"; + streamOff(); + requestBuffers(0); bufferPool_ = nullptr; From patchwork Wed Feb 13 15:10:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 573 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8A90C610B3 for ; Wed, 13 Feb 2019 16:10:33 +0100 (CET) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 29FF99B0; Wed, 13 Feb 2019 16:10:33 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1550070633; bh=q7Ytn3pTi34DJTXfOeovbc/1Zs5DwSIecgKK/3ycftU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LhpZuA6SHDjMgm0d2cR21KQM5tElNYKalZY0m5Sp/JISC2CTqAHHgDXSDfN4gCiqW ORVLtUuLdZnWG/1D1kxT75LfxFNonLo3liVZKsjsBMBTnCCTc5ozaotQMKjx7rJWxC pv9Fx6JWXBxIDv9TVtwaSQQnatpSGdgVrvbiJ/qk= From: Kieran Bingham To: LibCamera Devel Date: Wed, 13 Feb 2019 15:10:23 +0000 Message-Id: <20190213151027.6376-5-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190213151027.6376-1-kieran.bingham@ideasonboard.com> References: <20190213151027.6376-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 4/8] libcamera: v4l2_device: Support queueing buffers to an output device X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Feb 2019 15:10:33 -0000 To queue a buffer to an output device, we must set the buffer properties. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/libcamera/v4l2_device.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 83073c28b817..8c038239cf24 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -299,7 +299,15 @@ int V4L2Device::open() ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : V4L2_BUF_TYPE_VIDEO_OUTPUT; - fdEvent_ = new EventNotifier(fd_, EventNotifier::Read); + /* + * We wait for Read notifications on CAPTURE devices (POLLIN), and + * Write notifications for OUTPUT devices (POLLOUT). + */ + if (caps_.isCapture()) + fdEvent_ = new EventNotifier(fd_, EventNotifier::Read); + else + fdEvent_ = new EventNotifier(fd_, EventNotifier::Write); + fdEvent_->activated.connect(this, &V4L2Device::bufferAvailable); fdEvent_->setEnabled(false); @@ -679,6 +687,15 @@ int V4L2Device::queueBuffer(Buffer *buffer) buf.m.planes = planes; } + if (V4L2_TYPE_IS_OUTPUT(bufferType_)) { + buf.bytesused = buffer->bytesused_; + buf.sequence = buffer->sequence_; + /** + * \todo: Timestamp should be converted back to a struct + * timeval for passing back into V4L2. + */ + } + LOG(V4L2, Debug) << "Queueing buffer " << buf.index; ret = ioctl(fd_, VIDIOC_QBUF, &buf); From patchwork Wed Feb 13 15:10:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 574 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D0DA8610C8 for ; Wed, 13 Feb 2019 16:10:33 +0100 (CET) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6F97385; Wed, 13 Feb 2019 16:10:33 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1550070633; bh=dYjG83c6VptCUqY7LhSBvNFMu+c2KNqlfTY7UWDl0ZI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jya/kPrL4POq3FyiM4ogNrEvQO2r0kxrB+tbbQK4AGSyWsqJfPF+BvLbTDuj/Me5T /nPW9VkvhglgNQSZhQZAwT/7rrO3vSxKLWjmIVAH3eIvC0VEgzEKqEbQ1mqmLUcB6u giuJoMwoIS1QNPV2d9GP1ecnWif7xaUdqH4DXmGA= From: Kieran Bingham To: LibCamera Devel Date: Wed, 13 Feb 2019 15:10:24 +0000 Message-Id: <20190213151027.6376-6-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190213151027.6376-1-kieran.bingham@ideasonboard.com> References: <20190213151027.6376-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 5/8] libcamera: v4l2_device: Use non-interlaced frames X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Feb 2019 15:10:35 -0000 Use V4L2_FIELD_NONE where applicable to disable support for interlaced frames. We are unlikely to support interlaced frames on cameras so hardcode this field type for now. If we decide to support interlacing later it can be revisited. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/libcamera/v4l2_device.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 8c038239cf24..d690be9823f5 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -423,6 +423,7 @@ int V4L2Device::setFormatSingleplane(V4L2DeviceFormat *format) pix->height = format->height; pix->pixelformat = format->fourcc; pix->bytesperline = format->planes[0].bpl; + pix->field = V4L2_FIELD_NONE; ret = ioctl(fd_, VIDIOC_S_FMT, &v4l2Format); if (ret) { @@ -483,6 +484,7 @@ int V4L2Device::setFormatMultiplane(V4L2DeviceFormat *format) pix->height = format->height; pix->pixelformat = format->fourcc; pix->num_planes = format->planesCount; + pix->field = V4L2_FIELD_NONE; for (unsigned int i = 0; i < pix->num_planes; ++i) { pix->plane_fmt[i].bytesperline = format->planes[i].bpl; @@ -681,6 +683,7 @@ int V4L2Device::queueBuffer(Buffer *buffer) buf.index = buffer->index(); buf.type = bufferType_; buf.memory = memoryType_; + buf.field = V4L2_FIELD_NONE; if (V4L2_TYPE_IS_MULTIPLANAR(buf.type)) { buf.length = buffer->planes().size(); From patchwork Wed Feb 13 15:10:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 575 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 21601610C3 for ; Wed, 13 Feb 2019 16:10:34 +0100 (CET) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B6378304; Wed, 13 Feb 2019 16:10:33 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1550070633; bh=MhhgKgQyLFk+ylf1yHADPMsHipUjGgQGNCN/vzjWACQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=wFRAh4Vvx7OmybCIhOiCclrGIIZXulhHx5E4RbLytZwvkuHUYDoYDdWbHA6Vp5W93 mqW9WwpJ0BYvHjRIwJ0psnSMZRDGyQq/lrXt2OF3J08fStdGJXX8coc1+7AkHYKgRX yyh2iW1UEErwMC2kG/YtfIJWEfZlouWcA14mYlq4= From: Kieran Bingham To: LibCamera Devel Date: Wed, 13 Feb 2019 15:10:25 +0000 Message-Id: <20190213151027.6376-7-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190213151027.6376-1-kieran.bingham@ideasonboard.com> References: <20190213151027.6376-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 6/8] libcamera: v4l2_device: Simplify exportBuffers() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Feb 2019 15:10:35 -0000 exportBuffers() can only operate on an existing BufferPool allocation. The pool identifies its size through its .count() method. Passing a count in to the exportBuffers() call is redundant and can be incorrect if the value is not the same as the BufferPool size. Simplify the function and remove the unnecessary argument, correcting all uses throughout the code base. While we're here, remove the createBuffers() helper from the V4L2DeviceTest which only served to obfuscate which pool the buffers were being allocated for. Reviewed-by: Laurent Pinchart Signed-off-by: Kieran Bingham --- src/libcamera/include/v4l2_device.h | 2 +- src/libcamera/pipeline/ipu3/ipu3.cpp | 3 +-- src/libcamera/pipeline/uvcvideo.cpp | 2 +- src/libcamera/pipeline/vimc.cpp | 2 +- src/libcamera/v4l2_device.cpp | 15 ++++++--------- test/v4l2_device/capture_async.cpp | 4 ++-- test/v4l2_device/request_buffers.cpp | 4 ++-- test/v4l2_device/stream_on_off.cpp | 4 ++-- test/v4l2_device/v4l2_device_test.h | 2 -- 9 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_device.h index 983b9d900aea..5a536393a5b5 100644 --- a/src/libcamera/include/v4l2_device.h +++ b/src/libcamera/include/v4l2_device.h @@ -99,7 +99,7 @@ public: int getFormat(V4L2DeviceFormat *format); int setFormat(V4L2DeviceFormat *format); - int exportBuffers(unsigned int count, BufferPool *pool); + int exportBuffers(BufferPool *pool); int releaseBuffers(); int queueBuffer(Buffer *buffer); diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 34b03995ae31..677e127dd738 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -191,8 +191,7 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera, Stream *stream) if (!cfg.bufferCount) return -EINVAL; - int ret = data->cio2_->exportBuffers(cfg.bufferCount, - &stream->bufferPool()); + int ret = data->cio2_->exportBuffers(&stream->bufferPool()); if (ret) { LOG(IPU3, Error) << "Failed to request memory"; return ret; diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index fc31c52c0ecd..b6a98657b609 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -102,7 +102,7 @@ int PipelineHandlerUVC::allocateBuffers(Camera *camera, Stream *stream) LOG(UVC, Debug) << "Requesting " << cfg.bufferCount << " buffers"; - return video_->exportBuffers(cfg.bufferCount, &stream->bufferPool()); + return video_->exportBuffers(&stream->bufferPool()); } int PipelineHandlerUVC::freeBuffers(Camera *camera, Stream *stream) diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 46840a4f4104..543ff212d010 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -101,7 +101,7 @@ int PipelineHandlerVimc::allocateBuffers(Camera *camera, Stream *stream) LOG(VIMC, Debug) << "Requesting " << cfg.bufferCount << " buffers"; - return video_->exportBuffers(cfg.bufferCount, &stream->bufferPool()); + return video_->exportBuffers(&stream->bufferPool()); } int PipelineHandlerVimc::freeBuffers(Camera *camera, Stream *stream) diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index d690be9823f5..152bd9930a70 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -538,13 +538,12 @@ int V4L2Device::requestBuffers(unsigned int count) } /** - * \brief Request \a count buffers to be allocated from the device and stored in - * the buffer pool provided. - * \param[in] count Number of buffers to allocate + * \brief Request buffers to be allocated from the device and stored in the + * buffer pool provided. * \param[out] pool BufferPool to populate with buffers * \return 0 on success or a negative error code otherwise */ -int V4L2Device::exportBuffers(unsigned int count, BufferPool *pool) +int V4L2Device::exportBuffers(BufferPool *pool) { unsigned int allocatedBuffers; unsigned int i; @@ -552,21 +551,19 @@ int V4L2Device::exportBuffers(unsigned int count, BufferPool *pool) memoryType_ = V4L2_MEMORY_MMAP; - ret = requestBuffers(count); + ret = requestBuffers(pool->count()); if (ret < 0) return ret; allocatedBuffers = ret; - if (allocatedBuffers < count) { + if (allocatedBuffers < pool->count()) { LOG(V4L2, Error) << "Not enough buffers provided by V4L2Device"; requestBuffers(0); return -ENOMEM; } - count = ret; - /* Map the buffers. */ - for (i = 0; i < count; ++i) { + for (i = 0; i < pool->count(); ++i) { struct v4l2_plane planes[VIDEO_MAX_PLANES] = {}; struct v4l2_buffer buf = {}; struct Buffer &buffer = pool->buffers()[i]; diff --git a/test/v4l2_device/capture_async.cpp b/test/v4l2_device/capture_async.cpp index ba37c9731831..511368d6b53d 100644 --- a/test/v4l2_device/capture_async.cpp +++ b/test/v4l2_device/capture_async.cpp @@ -38,9 +38,9 @@ protected: Timer timeout; int ret; - createBuffers(bufferCount); + pool_.createBuffers(bufferCount); - ret = dev_->exportBuffers(bufferCount, &pool_); + ret = dev_->exportBuffers(&pool_); if (ret) return TestFail; diff --git a/test/v4l2_device/request_buffers.cpp b/test/v4l2_device/request_buffers.cpp index bc6ff2c18a57..26d7d9528982 100644 --- a/test/v4l2_device/request_buffers.cpp +++ b/test/v4l2_device/request_buffers.cpp @@ -19,9 +19,9 @@ protected: */ const unsigned int bufferCount = 8; - createBuffers(bufferCount); + pool_.createBuffers(bufferCount); - int ret = dev_->exportBuffers(bufferCount, &pool_); + int ret = dev_->exportBuffers(&pool_); if (ret) return TestFail; diff --git a/test/v4l2_device/stream_on_off.cpp b/test/v4l2_device/stream_on_off.cpp index b564d2a2ab67..861d8d695813 100644 --- a/test/v4l2_device/stream_on_off.cpp +++ b/test/v4l2_device/stream_on_off.cpp @@ -14,9 +14,9 @@ protected: { const unsigned int bufferCount = 8; - createBuffers(bufferCount); + pool_.createBuffers(bufferCount); - int ret = dev_->exportBuffers(bufferCount, &pool_); + int ret = dev_->exportBuffers(&pool_); if (ret) return TestFail; diff --git a/test/v4l2_device/v4l2_device_test.h b/test/v4l2_device/v4l2_device_test.h index f22f0bb555d8..43539655f85b 100644 --- a/test/v4l2_device/v4l2_device_test.h +++ b/test/v4l2_device/v4l2_device_test.h @@ -24,8 +24,6 @@ class V4L2DeviceTest : public Test public: V4L2DeviceTest() : dev_(nullptr){}; - void createBuffers(unsigned int qty) { pool_.createBuffers(qty); } - protected: int init(); void cleanup(); From patchwork Wed Feb 13 15:10:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 576 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 67BAB610BA for ; Wed, 13 Feb 2019 16:10:34 +0100 (CET) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0B2825B6; Wed, 13 Feb 2019 16:10:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1550070634; bh=Ws+N0xCxnDs84aCFjzVjARruxTpC8rxo6wO4uCAtdwQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FRbucWtGE7PlzdHp/y0Aqa7ApBy90gc/Sre7vE/5xmr1xugTssrgR4bOpUMachbfK DWOzNFkCvLowjpj3qEZBt/dzzS2DU5SdvJaZFdh8o3yTqVHFW5merakGkWF1GCRVjA mVb/jb0TAqVGUdYiGF/CB7sOgA4AOFNVO4lDtqow= From: Kieran Bingham To: LibCamera Devel Date: Wed, 13 Feb 2019 15:10:26 +0000 Message-Id: <20190213151027.6376-8-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190213151027.6376-1-kieran.bingham@ideasonboard.com> References: <20190213151027.6376-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 7/8] libcamera: v4l2_device: importBuffers support X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Feb 2019 15:10:35 -0000 Provide the ability to import a BufferPool into the V4L2Device allowing external dmabuf backed buffers to be queued. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/libcamera/include/v4l2_device.h | 1 + src/libcamera/v4l2_device.cpp | 45 ++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_device.h index 5a536393a5b5..1d31d1b403bc 100644 --- a/src/libcamera/include/v4l2_device.h +++ b/src/libcamera/include/v4l2_device.h @@ -100,6 +100,7 @@ public: int setFormat(V4L2DeviceFormat *format); int exportBuffers(BufferPool *pool); + int importBuffers(BufferPool *pool); int releaseBuffers(); int queueBuffer(Buffer *buffer); diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 152bd9930a70..2d0ce7011d8a 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -642,6 +642,36 @@ int V4L2Device::createPlane(Buffer *buffer, unsigned int planeIndex, return 0; } +/** + * \brief Import the externally allocated \a pool of buffers + * \param[in] pool BufferPool of buffers to import + * \return 0 on success or a negative error code otherwise + */ +int V4L2Device::importBuffers(BufferPool *pool) +{ + unsigned int allocatedBuffers; + int ret; + + memoryType_ = V4L2_MEMORY_DMABUF; + + ret = requestBuffers(pool->count()); + if (ret < 0) + return ret; + + allocatedBuffers = ret; + if (allocatedBuffers < pool->count()) { + LOG(V4L2, Error) + << "Not enough buffers provided by V4L2Device"; + requestBuffers(0); + return -ENOMEM; + } + + LOG(V4L2, Debug) << "Device using an externally provided pool"; + bufferPool_ = pool; + + return 0; +} + /** * \brief Release all internally allocated buffers */ @@ -682,7 +712,20 @@ int V4L2Device::queueBuffer(Buffer *buffer) buf.memory = memoryType_; buf.field = V4L2_FIELD_NONE; - if (V4L2_TYPE_IS_MULTIPLANAR(buf.type)) { + bool multiPlanar = V4L2_TYPE_IS_MULTIPLANAR(buf.type); + + if (buf.memory == V4L2_MEMORY_DMABUF) { + if (multiPlanar) { + for (unsigned int p = 0; + p < buffer->planes().size(); + p++) + planes[p].m.fd = buffer->planes()[p].dmabuf(); + } else { + buf.m.fd = buffer->planes()[0].dmabuf(); + } + } + + if (multiPlanar) { buf.length = buffer->planes().size(); buf.m.planes = planes; } From patchwork Wed Feb 13 15:10:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 577 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B601D610D5 for ; Wed, 13 Feb 2019 16:10:34 +0100 (CET) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 516AC85; Wed, 13 Feb 2019 16:10:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1550070634; bh=DTQoIzW920jrgfR9bqhstO727x6zqMU6XJrGHngA6pU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=C+LiVdpr4bcVnGUe1jTTGrGLsONO4xnjgMRSj51rOW/tYPcYgQSmRLV2kqT0C5CtM yz3XKQpE2kjWEWpSrQ4R37sDa6wsHYmZbV8/QOIzZ3zEpf/1hUvf0a5UHW+luGCD/f hyRAOJFk70ElClCzk9uAMrBLX2dF6PGorcQfAdm4= From: Kieran Bingham To: LibCamera Devel Date: Wed, 13 Feb 2019 15:10:27 +0000 Message-Id: <20190213151027.6376-9-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190213151027.6376-1-kieran.bingham@ideasonboard.com> References: <20190213151027.6376-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 8/8] test: v4l2_device: Provide buffer sharing test X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Feb 2019 15:10:35 -0000 Obtain two V4L2Devices and use one to obtain a BufferPool. Propagate the formats from the first to the second device and then commence sending buffers between the two devices in a ping-pong fashion. Signed-off-by: Kieran Bingham --- test/v4l2_device/buffer_sharing.cpp | 179 ++++++++++++++++++++++++++++ test/v4l2_device/meson.build | 1 + 2 files changed, 180 insertions(+) create mode 100644 test/v4l2_device/buffer_sharing.cpp diff --git a/test/v4l2_device/buffer_sharing.cpp b/test/v4l2_device/buffer_sharing.cpp new file mode 100644 index 000000000000..f03201e82084 --- /dev/null +++ b/test/v4l2_device/buffer_sharing.cpp @@ -0,0 +1,179 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * libcamera V4L2 API tests + * + * Validate the function of exporting buffers from a V4L2Device and + * the ability to import them to another V4L2Device instance. + * Ensure that the Buffers can successfully be queued and dequeued + * between both devices. + */ + +#include + +#include +#include +#include +#include + +#include "v4l2_device_test.h" + +#include "log.h" + +LOG_DEFINE_CATEGORY(Test) + +class BufferSharingTest : public V4L2DeviceTest +{ +public: + BufferSharingTest() + : output_(nullptr), framesCapture(0), framesOutput(0){}; + +private: + const unsigned int bufferCount = 4; + + V4L2Device *output_; + std::shared_ptr secondMedia_; + + unsigned int framesCapture; + unsigned int framesOutput; + +protected: + int init() + { + int ret = V4L2DeviceTest::init(); + if (ret) + return ret; + + /* media_ already represents VIVID */ + MediaEntity *entity = media_->getEntityByName("vivid-000-vid-out"); + if (!entity) + return TestSkip; + + output_ = new V4L2Device(entity); + if (!output_) + return TestFail; + + ret = output_->open(); + if (ret) + return TestFail; + + V4L2DeviceFormat format; + + ret = dev_->getFormat(&format); + if (ret) { + return TestFail; + } + + LOG(Test, Info) << "Successfully obtained format from source"; + + ret = output_->setFormat(&format); + if (ret) + return TestFail; + + LOG(Test, Info) << "Successfully set format to output"; + + pool_.createBuffers(bufferCount); + + ret = dev_->exportBuffers(&pool_); + if (ret) + return TestFail; + + ret = output_->importBuffers(&pool_); + if (ret) { + std::cerr << "Failed to import buffers" << std::endl; + return TestFail; + } + + return 0; + } + + void receiveSourceBuffer(Buffer *buffer) + { + std::cout << "Received source buffer: " << buffer->index() + << " sequence " << buffer->sequence() << std::endl; + + output_->queueBuffer(buffer); + framesCapture++; + } + + void receiveDestinationBuffer(Buffer *buffer) + { + std::cout << "Received destination buffer: " << buffer->index() + << " sequence " << buffer->sequence() << std::endl; + + dev_->queueBuffer(buffer); + framesOutput++; + } + + int run() + { + EventDispatcher *dispatcher = CameraManager::instance()->eventDispatcher(); + Timer timeout; + int ret; + + dev_->bufferReady.connect(this, &BufferSharingTest::receiveSourceBuffer); + output_->bufferReady.connect(this, &BufferSharingTest::receiveDestinationBuffer); + + /* Queue all the buffers to the device. */ + for (Buffer &b : pool_.buffers()) { + if (dev_->queueBuffer(&b)) + return TestFail; + } + + ret = dev_->streamOn(); + if (ret) + return TestFail; + + ret = output_->streamOn(); + if (ret) + return TestFail; + + timeout.start(10000); + while (timeout.isRunning()) { + dispatcher->processEvents(); + if (framesCapture > 30 && framesOutput > 30) + break; + } + + if ((framesCapture < 1) || (framesOutput < 1)) { + std::cout << "Failed to process any frames within timeout." << std::endl; + return TestFail; + } + + if ((framesCapture < 30) || (framesOutput < 30)) { + std::cout << "Failed to process 30 frames within timeout." << std::endl; + return TestFail; + } + + ret = dev_->streamOff(); + if (ret) + return TestFail; + + ret = output_->streamOff(); + if (ret) + return TestFail; + + return TestPass; + } + + void cleanup() + { + std::cout + << "Processed " << framesCapture << " capture frames" + << " and " << framesOutput << " output frames" + << std::endl; + + dev_->streamOff(); + output_->streamOff(); + + if (secondMedia_) + secondMedia_->release(); + + delete output_; + + V4L2DeviceTest::cleanup(); + } +}; + +TEST_REGISTER(BufferSharingTest); diff --git a/test/v4l2_device/meson.build b/test/v4l2_device/meson.build index ec2c7f9f11ff..9f7a7545ac9b 100644 --- a/test/v4l2_device/meson.build +++ b/test/v4l2_device/meson.build @@ -5,6 +5,7 @@ v4l2_device_tests = [ [ 'request_buffers', 'request_buffers.cpp' ], [ 'stream_on_off', 'stream_on_off.cpp' ], [ 'capture_async', 'capture_async.cpp' ], + [ 'buffer_sharing', 'buffer_sharing.cpp' ], ] foreach t : v4l2_device_tests