From patchwork Wed Sep 2 15:22:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 9471 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 777E6BE174 for ; Wed, 2 Sep 2020 15:19:11 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4CD4F629DF; Wed, 2 Sep 2020 17:19:11 +0200 (CEST) Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6F5C560374 for ; Wed, 2 Sep 2020 17:19:10 +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 relay1-d.mail.gandi.net (Postfix) with ESMTPSA id 4F635240017; Wed, 2 Sep 2020 15:19:09 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 2 Sep 2020 17:22:34 +0200 Message-Id: <20200902152236.69770-11-jacopo@jmondi.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200902152236.69770-1-jacopo@jmondi.org> References: <20200902152236.69770-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 10/12] android: camera_device: Rework CameraStream handling 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 CameraDevice::streams_ vector of CameraStream instances is currently mostly accessed by index. The current implementation creates all the CameraStream during the first loop that inspects the camera3_stream instances, and the update the index of the StreamConfiguration associated with the CameraStream during a second loop that inspects MJPEG streams. A third loop creates the JPEG encoder associated with CameraStreams that produce MJPEG format. As the index-based association is hard to follow and rather fragile, rework the creation and handling of CameraStream: 1) Make the StreamConfiguration index a constructor parameter and a private struct member. This disallow the creation of CameraStream without a StreamConfiguration index assigned. 2) Create CameraStream only after the associated StreamConfiguration has been identified. The first loop creates CameraStream for non-JPEG streams, the second for the JPEG ones after having identified the associated StreamConfiguration. Since we have just created the CameraStream, create the JPEG encoder at the same time instead of deferring it. This change removes all accesses by index to the CameraDevice::streams_ vector. No functional changes intended, but this change aims to make the code easier to follow and more robust. Reviewed-by: Kieran Bingham Signed-off-by: Jacopo Mondi --- src/android/camera_device.cpp | 75 +++++++++++++++++++---------------- src/android/camera_device.h | 18 +++++---- 2 files changed, 51 insertions(+), 42 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 3630e87e8814..9bcd1d993c17 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -168,8 +168,8 @@ MappedCamera3Buffer::MappedCamera3Buffer(const buffer_handle_t camera3buffer, } } -CameraStream::CameraStream(PixelFormat f, Size s) - : index(-1), format(f), size(s), jpeg(nullptr) +CameraStream::CameraStream(PixelFormat f, Size s, unsigned int i) + : format(f), size(s), jpeg(nullptr), index_(i) { } @@ -1212,30 +1212,28 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list) if (!format.isValid()) return -EINVAL; - streams_.emplace_back(format, size); - stream->priv = static_cast(&streams_[i]); - /* Defer handling of MJPEG streams until all others are known. */ if (stream->format == HAL_PIXEL_FORMAT_BLOB) continue; StreamConfiguration streamConfiguration; - streamConfiguration.size = size; streamConfiguration.pixelFormat = format; - streams_[i].index = config_->addConfiguration(streamConfiguration); + unsigned int index = config_->addConfiguration(streamConfiguration); + CameraStream &cameraStream = streams_.emplace_back(format, size, index); + stream->priv = static_cast(&cameraStream); } /* Now handle MJPEG streams, adding a new stream if required. */ for (unsigned int i = 0; i < stream_list->num_streams; ++i) { camera3_stream_t *stream = stream_list->streams[i]; - bool match = false; - if (stream->format != HAL_PIXEL_FORMAT_BLOB) continue; - /* Search for a compatible stream */ + /* Search for a compatible stream in the non-JPEG ones. */ + bool match = false; + unsigned int index; for (unsigned int j = 0; j < config_->size(); j++) { StreamConfiguration &cfg = config_->at(j); @@ -1243,13 +1241,15 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list) * \todo The PixelFormat must also be compatible with * the encoder. */ - if (cfg.size == streams_[i].size) { - LOG(HAL, Info) << "Stream " << i - << " using libcamera stream " << j; + if (cfg.size.width != stream->width || + cfg.size.height != stream->height) + continue; - match = true; - streams_[i].index = j; - } + LOG(HAL, Info) << "Stream " << i + << " using libcamera stream " << j; + + index = j; + match = true; } /* @@ -1272,7 +1272,26 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list) LOG(HAL, Info) << "Adding " << streamConfiguration.toString() << " for MJPEG support"; - streams_[i].index = config_->addConfiguration(streamConfiguration); + index = config_->addConfiguration(streamConfiguration); + } + + StreamConfiguration &cfg = config_->at(index); + PixelFormat format = formats::MJPEG; + Size size = cfg.size; + + CameraStream &cameraStream = streams_.emplace_back(format, size, index); + stream->priv = static_cast(&cameraStream); + + /* + * Construct a software encoder for MJPEG streams from the + * chosen libcamera source stream. + */ + cameraStream.jpeg = new EncoderLibJpeg(); + int ret = cameraStream.jpeg->configure(cfg); + if (ret) { + LOG(HAL, Error) + << "Failed to configure encoder"; + return ret; } } @@ -1295,25 +1314,11 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list) for (unsigned int i = 0; i < stream_list->num_streams; ++i) { camera3_stream_t *stream = stream_list->streams[i]; - CameraStream *cameraStream = &streams_[i]; - StreamConfiguration &cfg = config_->at(cameraStream->index); + CameraStream *cameraStream = static_cast(stream->priv); + StreamConfiguration &cfg = config_->at(cameraStream->index()); /* Use the bufferCount confirmed by the validation process. */ stream->max_buffers = cfg.bufferCount; - - /* - * Construct a software encoder for MJPEG streams from the - * chosen libcamera source stream. - */ - if (cameraStream->format == formats::MJPEG) { - cameraStream->jpeg = new EncoderLibJpeg(); - int ret = cameraStream->jpeg->configure(cfg); - if (ret) { - LOG(HAL, Error) - << "Failed to configure encoder"; - return ret; - } - } } /* @@ -1427,7 +1432,7 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques } descriptor->frameBuffers.emplace_back(buffer); - StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index); + StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index()); Stream *stream = streamConfiguration->stream(); request->addBuffer(stream, buffer); @@ -1482,7 +1487,7 @@ void CameraDevice::requestComplete(Request *request) continue; } - StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index); + StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index()); Stream *stream = streamConfiguration->stream(); FrameBuffer *buffer = request->findBuffer(stream); if (!buffer) { diff --git a/src/android/camera_device.h b/src/android/camera_device.h index dc0ee664d443..f8f237203ce9 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -28,20 +28,24 @@ class CameraMetadata; struct CameraStream { - CameraStream(libcamera::PixelFormat, libcamera::Size); +public: + CameraStream(libcamera::PixelFormat, libcamera::Size, unsigned int i); ~CameraStream(); - /* - * The index of the libcamera StreamConfiguration as added during - * configureStreams(). A single libcamera Stream may be used to deliver - * one or more streams to the Android framework. - */ - unsigned int index; + unsigned int index() const { return index_; } libcamera::PixelFormat format; libcamera::Size size; Encoder *jpeg; + +private: + /* + * The index of the libcamera StreamConfiguration as added during + * configureStreams(). A single libcamera Stream may be used to deliver + * one or more streams to the Android framework. + */ + unsigned int index_; }; class CameraDevice : protected libcamera::Loggable