From patchwork Wed Sep 2 10:47:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 9438 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 89E64BF019 for ; Wed, 2 Sep 2020 10:43:57 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 66702629B2; Wed, 2 Sep 2020 12:43:57 +0200 (CEST) Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 06D5A62931 for ; Wed, 2 Sep 2020 12:43:56 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 1679340009; Wed, 2 Sep 2020 10:43:54 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 2 Sep 2020 12:47:26 +0200 Message-Id: <20200902104730.43451-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200902104730.43451-1-jacopo@jmondi.org> References: <20200902104730.43451-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/5] android: camera_device: Refuse unsupported formats X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tfiga@google.com, hiroh@google.com Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The current implementation of CameraDevice::initializeStreamConfigurations() fails if an image format marked as mandatory is not supported by the libcamera::Camera device, but erroneously accepts non-mandatory non-supported formats in the list of accepted ones. Fix this by ignoring non supported image formats which are not marked as mandatory. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- src/android/camera_device.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 9605b9e9069e..ad0d7fd15d90 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -392,10 +392,16 @@ int CameraDevice::initializeStreamConfigurations() break; } } - if (camera3Format.mandatory && !mappedFormat.isValid()) { - LOG(HAL, Error) << "Failed to map Android format " - << camera3Format.name << " (" - << utils::hex(androidFormat) << ")"; + + if (!mappedFormat.isValid()) { + /* If the format is not mandatory, skip it. */ + if (!camera3Format.mandatory) + continue; + + LOG(HAL, Error) + << "Failed to map mandatory Android format " + << camera3Format.name << " (" + << utils::hex(androidFormat) << "): aborting"; return -EINVAL; } From patchwork Wed Sep 2 10:47:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 9439 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id AD13EBF019 for ; Wed, 2 Sep 2020 10:43:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 892A0629B8; Wed, 2 Sep 2020 12:43:58 +0200 (CEST) Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 193BE628EE for ; Wed, 2 Sep 2020 12:43:57 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 2D25C40003; Wed, 2 Sep 2020 10:43:56 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 2 Sep 2020 12:47:27 +0200 Message-Id: <20200902104730.43451-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200902104730.43451-1-jacopo@jmondi.org> References: <20200902104730.43451-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/5] android: camera_device: Generate JPEG sizes X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tfiga@google.com, hiroh@google.com Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" When producing the list of image resolution to claim as supported by the camera HAL, the JPEG stream was assumed to be 'always valid' as, at the time, there was no JPEG support in place at all. With the introduction of support for JPEG compression, reporting non-valid sizes as supported obviously causes troubles. In order to avoid reporting non-supported resolutions as supported, produce the list of available JPEG sizes by using the ones supported by the YCbCr_420_888 format, from which the JPEG stream is encoded. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- src/android/camera_device.cpp | 43 +++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index ad0d7fd15d90..8a8072123961 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -363,17 +363,27 @@ int CameraDevice::initializeStreamConfigurations() const std::vector &libcameraFormats = camera3Format.libcameraFormats; + /* + * Fixed format mapping for JPEG. + * + * The list of supported JPEG resolutions is generated + * from the list of resolutions supported by + * HAL_PIXEL_FORMAT_YCbCr_420_888 from which JPEG is produced. + * + * \todo Wire the JPEG encoder interface to query the list + * of supported resolutions. + */ + if (androidFormat == HAL_PIXEL_FORMAT_BLOB) { + formatsMap_[androidFormat] = formats::MJPEG; + continue; + } + /* * Test the libcamera formats that can produce images * compatible with the format defined by Android. */ PixelFormat mappedFormat; for (const PixelFormat &pixelFormat : libcameraFormats) { - /* \todo Fixed mapping for JPEG. */ - if (androidFormat == HAL_PIXEL_FORMAT_BLOB) { - mappedFormat = formats::MJPEG; - break; - } /* * The stream configuration size can be adjusted, @@ -416,19 +426,22 @@ int CameraDevice::initializeStreamConfigurations() cfg.size = res; CameraConfiguration::Status status = cameraConfig->validate(); - /* - * Unconditionally report we can produce JPEG. - * - * \todo The JPEG stream will be implemented as an - * HAL-only stream, but some cameras can produce it - * directly. As of now, claim support for JPEG without - * inspecting where the JPEG stream is produced. - */ - if (androidFormat != HAL_PIXEL_FORMAT_BLOB && - status != CameraConfiguration::Valid) + if (status != CameraConfiguration::Valid) continue; streamConfigurations_.push_back({ res, androidFormat }); + + /* + * If the format is HAL_PIXEL_FORMAT_YCbCr_420_888 + * from which JPEG is produced, add an entry for + * the JPEG stream. + * + * \todo Wire the JPEG encoder to query the supported + * sizes provided a list of formats it can encode. + */ + if (androidFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) + streamConfigurations_.push_back( + { res, HAL_PIXEL_FORMAT_BLOB }); } } From patchwork Wed Sep 2 10:47:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 9440 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id DADB8BF019 for ; Wed, 2 Sep 2020 10:43:59 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B6D73629BF; Wed, 2 Sep 2020 12:43:59 +0200 (CEST) Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2B0E1628EE for ; Wed, 2 Sep 2020 12:43:58 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 3E46640009; Wed, 2 Sep 2020 10:43:57 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 2 Sep 2020 12:47:28 +0200 Message-Id: <20200902104730.43451-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200902104730.43451-1-jacopo@jmondi.org> References: <20200902104730.43451-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/5] android: camera_device: Add debug to stream initialization X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tfiga@google.com, hiroh@google.com Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add debug printouts to the CameraDevice::initializeStreamConfigurations() function that helps to follow the process of building the stream configurations map. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- src/android/camera_device.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 8a8072123961..493d6cecde72 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -363,6 +363,9 @@ int CameraDevice::initializeStreamConfigurations() const std::vector &libcameraFormats = camera3Format.libcameraFormats; + LOG(HAL, Debug) << "Testing Android format: " + << camera3Format.name; + /* * Fixed format mapping for JPEG. * @@ -375,6 +378,10 @@ int CameraDevice::initializeStreamConfigurations() */ if (androidFormat == HAL_PIXEL_FORMAT_BLOB) { formatsMap_[androidFormat] = formats::MJPEG; + LOG(HAL, Debug) << "Mapped Android format: " + << camera3Format.name << " to: " + << formats::MJPEG.toString() + << " (fixed mapping)"; continue; } @@ -385,6 +392,10 @@ int CameraDevice::initializeStreamConfigurations() PixelFormat mappedFormat; for (const PixelFormat &pixelFormat : libcameraFormats) { + LOG(HAL, Debug) << "Testing Android format: " + << camera3Format.name << " with: " + << pixelFormat.toString(); + /* * The stream configuration size can be adjusted, * not the pixel format. @@ -420,14 +431,27 @@ int CameraDevice::initializeStreamConfigurations() * stream configurations map, by testing the image resolutions. */ formatsMap_[androidFormat] = mappedFormat; + LOG(HAL, Debug) << "Mapped Android format: " + << camera3Format.name << " to: " + << mappedFormat.toString(); for (const Size &res : cameraResolutions) { cfg.pixelFormat = mappedFormat; cfg.size = res; + std::stringstream ss; + ss << "Testing (" << res.toString() << ")[" + << mappedFormat.toString() << "]: "; + CameraConfiguration::Status status = cameraConfig->validate(); - if (status != CameraConfiguration::Valid) + if (status != CameraConfiguration::Valid) { + ss << " not supported"; + LOG(HAL, Debug) << ss.str(); continue; + } + + ss << " supported"; + LOG(HAL, Debug) << ss.str(); streamConfigurations_.push_back({ res, androidFormat }); From patchwork Wed Sep 2 10:47:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 9441 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 18C72BF019 for ; Wed, 2 Sep 2020 10:44:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E5439629B2; Wed, 2 Sep 2020 12:44:00 +0200 (CEST) Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 32CA8628EE for ; Wed, 2 Sep 2020 12:43:59 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 4942440003; Wed, 2 Sep 2020 10:43:58 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 2 Sep 2020 12:47:29 +0200 Message-Id: <20200902104730.43451-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200902104730.43451-1-jacopo@jmondi.org> References: <20200902104730.43451-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 4/5] android: camera_device: Break out size calculation X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tfiga@google.com, hiroh@google.com Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" As the RAW stream sizes needs to be calculated differently from the processed one, break out from the initializeStreamConfigurations() function the procedure to calculate the processed (RGB/YUV) resolutions in order to prepare for RAW sizes calculation. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- src/android/camera_device.cpp | 55 ++++++++++++++++++++++++----------- src/android/camera_device.h | 5 ++++ 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 493d6cecde72..765c3292e4f3 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -283,6 +283,37 @@ int CameraDevice::initialize() return ret; } +std::vector CameraDevice::listProcessedResolutions(CameraConfiguration *cameraConfig, + const PixelFormat &pixelFormat, + const std::vector &resolutions) +{ + std::vector supportedResolutions; + + StreamConfiguration &cfg = cameraConfig->at(0); + for (const Size &res : resolutions) { + cfg.pixelFormat = pixelFormat; + cfg.size = res; + + std::stringstream ss; + ss << "Tested (" << res.toString() << ")[" + << pixelFormat.toString() << "]: "; + + CameraConfiguration::Status status = cameraConfig->validate(); + if (status != CameraConfiguration::Valid) { + ss << " not supported"; + LOG(HAL, Debug) << ss.str(); + continue; + } + + ss << " supported"; + LOG(HAL, Debug) << ss.str(); + + supportedResolutions.push_back(res); + } + + return supportedResolutions; +} + /* * Initialize the format conversion map to translate from Android format * identifier to libcamera pixel formats and fill in the list of supported @@ -435,24 +466,14 @@ int CameraDevice::initializeStreamConfigurations() << camera3Format.name << " to: " << mappedFormat.toString(); - for (const Size &res : cameraResolutions) { - cfg.pixelFormat = mappedFormat; - cfg.size = res; - - std::stringstream ss; - ss << "Testing (" << res.toString() << ")[" - << mappedFormat.toString() << "]: "; - - CameraConfiguration::Status status = cameraConfig->validate(); - if (status != CameraConfiguration::Valid) { - ss << " not supported"; - LOG(HAL, Debug) << ss.str(); - continue; - } - - ss << " supported"; - LOG(HAL, Debug) << ss.str(); + const PixelFormatInfo &info = PixelFormatInfo::info(mappedFormat); + if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) + continue; + std::vector resolutions = listProcessedResolutions(cameraConfig.get(), + mappedFormat, + cameraResolutions); + for (const Size &res : resolutions) { streamConfigurations_.push_back({ res, androidFormat }); /* diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 3934f194f1b5..18fd5ff03cde 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -93,6 +93,11 @@ private: }; int initializeStreamConfigurations(); + std::vector + listProcessedResolutions(libcamera::CameraConfiguration *cameraConfig, + const libcamera::PixelFormat &pixelFormat, + const std::vector &resolutions); + std::tuple calculateStaticMetadataSize(); libcamera::FrameBuffer *createFrameBuffer(const buffer_handle_t camera3buffer); void notifyShutter(uint32_t frameNumber, uint64_t timestamp); From patchwork Wed Sep 2 10:47:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 9442 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 4D817BF019 for ; Wed, 2 Sep 2020 10:44:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 278CC62997; Wed, 2 Sep 2020 12:44:02 +0200 (CEST) Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 36D1B628EE for ; Wed, 2 Sep 2020 12:44:00 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 58C2940009; Wed, 2 Sep 2020 10:43:59 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 2 Sep 2020 12:47:30 +0200 Message-Id: <20200902104730.43451-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200902104730.43451-1-jacopo@jmondi.org> References: <20200902104730.43451-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 5/5] android: camera_device: List RAW resolutions X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tfiga@google.com, hiroh@google.com Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The resolutions supported for the RAW formats cannot be tested from a list of known sizes like the processed ones. This is mainly due to the fact RAW streams are produced by capturing frames at the CSI-2 receiver output and their size corresponds to the sensor's native sizes. In order to obtain the RAW frame size generate a temporary CameraConfiguration for the Role::StillCaptureRAW role and inspect the map of StreamFormats returned by the pipeline handler. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- src/android/camera_device.cpp | 21 +++++++++++++++++---- src/android/camera_device.h | 2 ++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 765c3292e4f3..181fca83988d 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -314,6 +314,17 @@ std::vector CameraDevice::listProcessedResolutions(CameraConfiguration *ca return supportedResolutions; } +std::vector CameraDevice::listRawResolutions(const libcamera::PixelFormat &pixelFormat) +{ + std::unique_ptr cameraConfig = + camera_->generateConfiguration({ StillCaptureRaw }); + StreamConfiguration &cfg = cameraConfig->at(0); + const StreamFormats &formats = cfg.formats(); + std::vector supportedResolutions = formats.sizes(pixelFormat); + + return supportedResolutions; +} + /* * Initialize the format conversion map to translate from Android format * identifier to libcamera pixel formats and fill in the list of supported @@ -466,13 +477,15 @@ int CameraDevice::initializeStreamConfigurations() << camera3Format.name << " to: " << mappedFormat.toString(); + std::vector resolutions; const PixelFormatInfo &info = PixelFormatInfo::info(mappedFormat); if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) - continue; + resolutions = listRawResolutions(mappedFormat); + else + resolutions = listProcessedResolutions(cameraConfig.get(), + mappedFormat, + cameraResolutions); - std::vector resolutions = listProcessedResolutions(cameraConfig.get(), - mappedFormat, - cameraResolutions); for (const Size &res : resolutions) { streamConfigurations_.push_back({ res, androidFormat }); diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 18fd5ff03cde..230e89b011e6 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -97,6 +97,8 @@ private: listProcessedResolutions(libcamera::CameraConfiguration *cameraConfig, const libcamera::PixelFormat &pixelFormat, const std::vector &resolutions); + std::vector + listRawResolutions(const libcamera::PixelFormat &pixelFormat); std::tuple calculateStaticMetadataSize(); libcamera::FrameBuffer *createFrameBuffer(const buffer_handle_t camera3buffer);