From patchwork Thu May 12 10:32:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 15897 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 C53DCC3256 for ; Thu, 12 May 2022 10:33:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5195E6049E; Thu, 12 May 2022 12:33:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1652351589; bh=MW0offhMoJI/VCah591TiXh7bqFR0DpG7E9GcFsGS4Q=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=wPydZUyDwIGQiyJrPmiDlaq4HMokGoXv8ckBuDSG9AllFe9JUHy36IuoQ+sUSeii0 FUzpzM1PP2Ekkb6YpjOzRkyYaaRz5iD0CrV2QBGZPOXhmUbFCf/7D/oA/j4cDXNjYF uJSSD02OCL0ba9Vl36FlSVQ6HyiBc2XXiUhxsrOyc/GS8xwH8xGoweR/NqpOR/4g4n JIAF1VSeKEG0gDYX7Yc323pNagWKD3LO9jZC65rlrcgbkIrKv8dFk/TJOeZkDJ8gUr cZL768wbROVI/yDYPpzn7O7BfoydMW0qUlaOrQ14bXR4PR7DZ4oHXMhRPpR6G/C4t6 /MvpAC0XErcUw== Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7615C6049E for ; Thu, 12 May 2022 12:33:06 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="KLggY4gA"; dkim-atps=neutral Received: by mail-pl1-x635.google.com with SMTP id q18so4443104pln.12 for ; Thu, 12 May 2022 03:33:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/RLoL25Tv7rJr7zr2WqE+km06ZA1O+F8o2ekb2BaZe8=; b=KLggY4gAofckSdnpElKIaVomU+ofBq8ojFDltZ2cOCwq2DjDCedQdjq3Z3/slApWOD WsoAirNij/DHmdXIRTNxMSAkjLg5BZh3EEft07WT4lheTSkYKdx8qL2MBpA/uSJwGOO1 ESbMTlXPUql0pq9BkbLDl047oiCamIQbMCRKk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/RLoL25Tv7rJr7zr2WqE+km06ZA1O+F8o2ekb2BaZe8=; b=1SQm2E4uZf7HiJZx9rkW2ptcQR+f+aREDpEOpOM0x38V38VE/OoFayDSt+Wg+pzkNn WtdwKWNbJ2TI7qT1D7nKWsphAvLS54IZvAZlB2BGI510ELzxGaqWER0LE7r+20Iq5O2B Ivy4/QGgfi5sppYzvZUZiTK/yn3zAHTJNIQUdHodKAU5C+psSJUoVWZcGJfuR6eL4B5e pOdnreBU/gTBeDAMzKEe3jBoEk8s74vfcC6bmdj+UnJ8Gi6Zgqtuupw8TKYIPEZMCM8C h7nqlZtWRCu0oSmAAFxNCovglxfNZPD+pFHxcchQ7WsObGGg3du4BTPJhitsV9NE+X2D DtMg== X-Gm-Message-State: AOAM5329XwT5DtcuSKHCfEF/rpBZtFYSWVFUU1dK2JT53OhHuViTl7zL yBF81lmgmZ6lQ9cu7jVQJsIa4+om6KSraNz5 X-Google-Smtp-Source: ABdhPJxt7je/CJpTrF6EzosuK7pwJDrLTu30mWLi3pf4prYd0xvlplKLEAvDRV4p5UU4qYyLvuE48g== X-Received: by 2002:a17:902:ea11:b0:15e:ae19:f36a with SMTP id s17-20020a170902ea1100b0015eae19f36amr29750066plg.52.1652351584694; Thu, 12 May 2022 03:33:04 -0700 (PDT) Received: from chenghaoyang-low.c.googlers.com.com (174.71.80.34.bc.googleusercontent.com. [34.80.71.174]) by smtp.gmail.com with ESMTPSA id t19-20020a62d153000000b005087c23ad8dsm3402219pfl.0.2022.05.12.03.33.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 12 May 2022 03:33:04 -0700 (PDT) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 12 May 2022 10:32:51 +0000 Message-Id: <20220512103258.324339-2-chenghaoyang@google.com> X-Mailer: git-send-email 2.36.0.512.ge40c2bad7a-goog In-Reply-To: <20220512103258.324339-1-chenghaoyang@google.com> References: <20220512103258.324339-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/8] Add StreamRole in StreamConfiguration 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: , X-Patchwork-Original-From: Harvey Yang via libcamera-devel From: Cheng-Hao Yang Reply-To: Harvey Yang Cc: Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Harvey Yang To let ipu3 pipeline handler understand the usage of streams, this patch adds StreamRole member variable in StreamConfiguration, which should be set by the (Android) adapter. Signed-off-by: Harvey Yang --- include/libcamera/stream.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h index f0ae7e62..c9e79226 100644 --- a/include/libcamera/stream.h +++ b/include/libcamera/stream.h @@ -22,6 +22,15 @@ namespace libcamera { class Camera; class Stream; +enum StreamRole { + Raw, + StillCapture, + VideoRecording, + Viewfinder, +}; + +using StreamRoles = std::vector; + class StreamFormats { public: @@ -50,6 +59,8 @@ struct StreamConfiguration { std::optional colorSpace; + StreamRole streamRole; + Stream *stream() const { return stream_; } void setStream(Stream *stream) { stream_ = stream; } const StreamFormats &formats() const { return formats_; } @@ -61,15 +72,6 @@ private: StreamFormats formats_; }; -enum StreamRole { - Raw, - StillCapture, - VideoRecording, - Viewfinder, -}; - -using StreamRoles = std::vector; - class Stream { public: From patchwork Thu May 12 10:32:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 15898 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 CF257C326C for ; Thu, 12 May 2022 10:33:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0C65065641; Thu, 12 May 2022 12:33:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1652351590; bh=wukPARUiUSFLdffEzZ5nRpJD5im1hAxRriQA2ITD1Wo=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=vmU44JqLm7Dx+nwZTSyFSNSAo6Oqy6eP1K9PCm2Zb3DyGv47E6e/jgS5J6o151z6Q 8duq1jxdlWvmSGS+OW8jMFPivW/VuUzwNlhahyf2u6nUh3wwor1uPqHKtCpMb0cLtf uhhQmyAfRhnX3aEgHCwtNTiDxY/qkkRlBBjRDnAiLAD9Sk13gMYPNVtikI0oS+gTP3 35VDOXEMNCkPrROo4/29ZWC8lhLo2tpktC3N9bzTdxkB/ENUg1tTAeBBbRmn5zG2+S N7QBYYd1ZSZtTUuXk/28W4AaFeiCvO6o16joEDB7h3YE5N0VQgbD1AYyJyrltxOFOE JEbjiI2unCgbA== Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 53D8C6049E for ; Thu, 12 May 2022 12:33:08 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="m6YhqHrw"; dkim-atps=neutral Received: by mail-pj1-x1030.google.com with SMTP id cq17-20020a17090af99100b001dc0386cd8fso4485950pjb.5 for ; Thu, 12 May 2022 03:33:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=WfSb3RCwf0H+pQuNDVNprdxG0GnEl0+4yWxd1rNIr2s=; b=m6YhqHrwMucCYo1a1/16vsGpwREEBhSGG4qQO2tFYO2MKcPgkMuiSDUprqt5mGYA41 gWTEYY/DiMppbFvIgd57o+SHy8i+wlyMpLN2nh3G2MPs+c7I/FgIX2wpjgFGRjsewqmi RlrXHz/0YXUtFT2c4gZzmD/ordmmcRCSZXvzI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=WfSb3RCwf0H+pQuNDVNprdxG0GnEl0+4yWxd1rNIr2s=; b=kzxHz1dqIu4Mb0Y7eMuGtbNI85duPcXEGnTBVHRh161WPbfSlUGj/y0h6Z3CJgxcD7 QlaHCljTqlKyIe7bNMlR6wfBaE0NMQpdPfabc1XEtHEh7dJ/UxR9Iq9no62CqH7PGa6O dvYFgs9Uv2cC6FSWrvsr4NRjT5R64kqkv6RkhUdeotR5tFwDFFFcud1ljoNAhF+3wrRo 0BVxfbRrYKN86Kff0/Pgil5tfZ69kC3nATu3gKmRVAncNWK44Vhy3/zSXcJKFlJGAN4m 1S20ZL5LU+OYHAHLNx6iYWBU59rDlyktlyWOfmkMwZUe/L3R/XgyjmHAiKNi/GtMjRWy G4yw== X-Gm-Message-State: AOAM532KsrJyISIAqKXO8XYKOs+a3IWwopy4KtBGXZFI+jbgAXUGsl75 B4qrQy64LlGODi7HgPGyUcYspG2sDCf13ZVl X-Google-Smtp-Source: ABdhPJxqeSsgi61fGU6pt9az3QNZiR5TXmH09IhGILKa75wV/NLKGhtPLFl0YilBshP0g28li0ULUw== X-Received: by 2002:a17:902:ce92:b0:15e:9601:dc02 with SMTP id f18-20020a170902ce9200b0015e9601dc02mr28740393plg.79.1652351586314; Thu, 12 May 2022 03:33:06 -0700 (PDT) Received: from chenghaoyang-low.c.googlers.com.com (174.71.80.34.bc.googleusercontent.com. [34.80.71.174]) by smtp.gmail.com with ESMTPSA id t19-20020a62d153000000b005087c23ad8dsm3402219pfl.0.2022.05.12.03.33.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 12 May 2022 03:33:05 -0700 (PDT) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 12 May 2022 10:32:52 +0000 Message-Id: <20220512103258.324339-3-chenghaoyang@google.com> X-Mailer: git-send-email 2.36.0.512.ge40c2bad7a-goog In-Reply-To: <20220512103258.324339-1-chenghaoyang@google.com> References: <20220512103258.324339-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/8] Allow only one camera being started 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: , X-Patchwork-Original-From: Harvey Yang via libcamera-devel From: Cheng-Hao Yang Reply-To: Harvey Yang Cc: Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Harvey Yang As we hardly have use cases/applications that need both cameras at the same time, this patch adds a rule that only one camera can be started one time. This also allows the following patches that use both imgus to process frames from one single camera. Signed-off-by: Harvey Yang --- src/libcamera/pipeline/ipu3/ipu3.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index fd989e61..111ba053 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -166,6 +166,8 @@ private: MediaDevice *cio2MediaDev_; MediaDevice *imguMediaDev_; + Camera *inUseCamera_ = nullptr; + std::vector ipaBuffers_; }; @@ -765,6 +767,10 @@ int PipelineHandlerIPU3::freeBuffers(Camera *camera) int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] const ControlList *controls) { + // Deny second camera being started. + if (inUseCamera_ && inUseCamera_ != camera) + return -1; + IPU3CameraData *data = cameraData(camera); CIO2Device *cio2 = &data->cio2_; ImgUDevice *imgu = data->imgu_; @@ -781,6 +787,8 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] const ControlLis if (ret) return ret; + inUseCamera_ = camera; + ret = data->ipa_->start(); if (ret) goto error; @@ -808,6 +816,8 @@ error: freeBuffers(camera); LOG(IPU3, Error) << "Failed to start camera " << camera->id(); + inUseCamera_ = nullptr; + return ret; } @@ -826,6 +836,8 @@ void PipelineHandlerIPU3::stopDevice(Camera *camera) LOG(IPU3, Warning) << "Failed to stop camera " << camera->id(); freeBuffers(camera); + + inUseCamera_ = nullptr; } void IPU3CameraData::cancelPendingRequests() From patchwork Thu May 12 10:32:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 15899 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 BB9D7C3256 for ; Thu, 12 May 2022 10:33:11 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 746F365666; Thu, 12 May 2022 12:33:11 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1652351591; bh=SA3x853iYpMjSAV0dBy2JefOlLjk94LRbL2O21yu0Pk=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=PH/PFHzt/aBv10FlLU21dWLNsKFbMMP/vbAlg5umXyGdPUyTVz41hnERjogjxYlun 9qT3rzTvqOWsJCZRIEwNA3QVxsJUD6EviUkoPb8ays1jt+ECtt6Zv8bqrdHAJQhnjQ Sl53S8hZFHnK1T44IGeTdz7lGwuzCL8vwelJsDNyX/yYXjzHCNK4o5mEsUIsP0RveY BYzgpXtchUtJzdI9MpIu/MSc2E042IMVmiIlJh2PbNczqjqSbjb5ExODRAjzUoAb9j GVxr+3+VR+uyg2XbqidjLlhSasr7gM/Mk+IZrkXvoYcV9DthYTnKfnLLhvf0rUxHy1 HgSbeDyRZqz+w== Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0958565641 for ; Thu, 12 May 2022 12:33:09 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="ERpRvZRn"; dkim-atps=neutral Received: by mail-pj1-x1030.google.com with SMTP id cq17-20020a17090af99100b001dc0386cd8fso4485950pjb.5 for ; Thu, 12 May 2022 03:33:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=FRUFoZcbRLEU/0iUZWg2v4aaKCgp6exIn71fmvTYPjo=; b=ERpRvZRn9T0aXB10zYvarDICsSo1m/LoGxoBUg2lannqbNbYyUPSzMn+P7Gh1pW5FU 5YnqV0QjtlA2VXUG6mIBN77j38cg5zlYYV8TYWJCC/W3Xdpxjk01JsXJwyTSW8duhSjn 7+azrN5X6FYhB/4b6lMAei8B4hxOADTVIyQqg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=FRUFoZcbRLEU/0iUZWg2v4aaKCgp6exIn71fmvTYPjo=; b=C7Vukp+QPymOWXWe2d4B0USqNqmtq2k0RqxN6VZhc0eeh5ne2bMF9n/mhYn+5ML5ai Yw5rKFIZY6Q18MJpSy2zWN/eaLPvFsy0W6Al26UHSPx3y8dySRee8ykLl61ri62VwZZe yw5SJScQQgO+Ytwt+KWPTdcFZjbaF+ekZKtogb2JqjdQa8jqDnQ97MPA/3uA0xkFq+Hz EasONeM+277wF2V6ayV8MPDRhotD+0bLC5gKQ2NSvTHhtMLV8lNds2DpQL+wMQMhyjSH 77VB8A3TY8pjMlqNiRppKgbhJtB/IF6vh+/vGmAA21/jMs4lL0CrTzwGTmGCRtPgbgVn 3/rA== X-Gm-Message-State: AOAM533DN1/qkorSSH1jy1RmkCrBMUEoii2CPOK70oXJI5j5CB368TMw XgdT6foJTjXy0efdJu7A+C3WQFs7fWn4hrXp X-Google-Smtp-Source: ABdhPJzY1JliQZVM28CzphxbiJPzopK0YxUiK6wJkrpPJT4KsrLzbfZLgvRqW95DObfi/sQ6+OrcOQ== X-Received: by 2002:a17:902:db05:b0:15e:d003:54f2 with SMTP id m5-20020a170902db0500b0015ed00354f2mr29376098plx.103.1652351588086; Thu, 12 May 2022 03:33:08 -0700 (PDT) Received: from chenghaoyang-low.c.googlers.com.com (174.71.80.34.bc.googleusercontent.com. [34.80.71.174]) by smtp.gmail.com with ESMTPSA id t19-20020a62d153000000b005087c23ad8dsm3402219pfl.0.2022.05.12.03.33.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 12 May 2022 03:33:07 -0700 (PDT) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 12 May 2022 10:32:53 +0000 Message-Id: <20220512103258.324339-4-chenghaoyang@google.com> X-Mailer: git-send-email 2.36.0.512.ge40c2bad7a-goog In-Reply-To: <20220512103258.324339-1-chenghaoyang@google.com> References: <20220512103258.324339-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/8] Use imgu0 as default 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: , X-Patchwork-Original-From: Harvey Yang via libcamera-devel From: Cheng-Hao Yang Reply-To: Harvey Yang Cc: Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Harvey Yang With only one camera being started, we can always use imgu0 to process frames (for video/preview). In the following patches, we'll use imgu1 for still capture if needed. Signed-off-by: Harvey Yang --- src/libcamera/pipeline/ipu3/ipu3.cpp | 86 ++++++++++++++++------------ 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 111ba053..5dd13c41 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -64,7 +64,8 @@ public: void frameStart(uint32_t sequence); CIO2Device cio2_; - ImgUDevice *imgu_; + ImgUDevice *imgu0_; + ImgUDevice *imgu1_; Stream outStream_; Stream vfStream_; @@ -406,7 +407,7 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() /* Only compute the ImgU configuration if a YUV stream has been requested. */ if (yuvCount) { - pipeConfig_ = data_->imgu_->calculatePipeConfig(&pipe); + pipeConfig_ = data_->imgu0_->calculatePipeConfig(&pipe); if (pipeConfig_.isNull()) { LOG(IPU3, Error) << "Failed to calculate pipe configuration: " << "unsupported resolutions."; @@ -518,7 +519,6 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) Stream *outStream = &data->outStream_; Stream *vfStream = &data->vfStream_; CIO2Device *cio2 = &data->cio2_; - ImgUDevice *imgu = data->imgu_; V4L2DeviceFormat outputFormat; int ret; @@ -560,7 +560,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) * stream which is for raw capture, in which case no buffers will * ever be queued to the ImgU. */ - ret = data->imgu_->enableLinks(true); + ret = imgu0_.enableLinks(true); if (ret) return ret; @@ -610,7 +610,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) if (imguConfig.isNull()) return 0; - ret = imgu->configure(imguConfig, &cio2Format); + ret = imgu0_.configure(imguConfig, &cio2Format); if (ret) return ret; @@ -624,12 +624,12 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) if (stream == outStream) { mainCfg = &cfg; - ret = imgu->configureOutput(cfg, &outputFormat); + ret = imgu0_.configureOutput(cfg, &outputFormat); if (ret) return ret; } else if (stream == vfStream) { vfCfg = &cfg; - ret = imgu->configureViewfinder(cfg, &outputFormat); + ret = imgu0_.configureViewfinder(cfg, &outputFormat); if (ret) return ret; } @@ -641,13 +641,13 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) * be at least one active stream in the configuration request). */ if (!vfCfg) { - ret = imgu->configureViewfinder(*mainCfg, &outputFormat); + ret = imgu0_.configureViewfinder(*mainCfg, &outputFormat); if (ret) return ret; } /* Apply the "pipe_mode" control to the ImgU subdevice. */ - ControlList ctrls(imgu->imgu_->controls()); + ControlList ctrls(imgu0_.imgu_->controls()); /* * Set the ImgU pipe mode to 'Video' unconditionally to have statistics * generated. @@ -657,7 +657,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) */ ctrls.set(V4L2_CID_IPU3_PIPE_MODE, static_cast(IPU3PipeModeVideo)); - ret = imgu->imgu_->setControls(&ctrls); + ret = imgu0_.imgu_->setControls(&ctrls); if (ret) { LOG(IPU3, Error) << "Unable to set pipe_mode control"; return ret; @@ -691,9 +691,9 @@ int PipelineHandlerIPU3::exportFrameBuffers(Camera *camera, Stream *stream, unsigned int count = stream->configuration().bufferCount; if (stream == &data->outStream_) - return data->imgu_->output_->exportBuffers(count, buffers); + return imgu0_.output_->exportBuffers(count, buffers); else if (stream == &data->vfStream_) - return data->imgu_->viewfinder_->exportBuffers(count, buffers); + return imgu0_.viewfinder_->exportBuffers(count, buffers); else if (stream == &data->rawStream_) return data->cio2_.exportBuffers(count, buffers); @@ -711,7 +711,6 @@ int PipelineHandlerIPU3::exportFrameBuffers(Camera *camera, Stream *stream, int PipelineHandlerIPU3::allocateBuffers(Camera *camera) { IPU3CameraData *data = cameraData(camera); - ImgUDevice *imgu = data->imgu_; unsigned int bufferCount; int ret; @@ -721,26 +720,26 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera) data->rawStream_.configuration().bufferCount, }); - ret = imgu->allocateBuffers(bufferCount); + ret = imgu0_.allocateBuffers(bufferCount); if (ret < 0) return ret; /* Map buffers to the IPA. */ unsigned int ipaBufferId = 1; - for (const std::unique_ptr &buffer : imgu->paramBuffers_) { + for (const std::unique_ptr &buffer : imgu0_.paramBuffers_) { buffer->setCookie(ipaBufferId++); ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes()); } - for (const std::unique_ptr &buffer : imgu->statBuffers_) { + for (const std::unique_ptr &buffer : imgu0_.statBuffers_) { buffer->setCookie(ipaBufferId++); ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes()); } data->ipa_->mapBuffers(ipaBuffers_); - data->frameInfos_.init(imgu->paramBuffers_, imgu->statBuffers_); + data->frameInfos_.init(imgu0_.paramBuffers_, imgu0_.statBuffers_); data->frameInfos_.bufferAvailable.connect( data, &IPU3CameraData::queuePendingRequests); @@ -760,7 +759,7 @@ int PipelineHandlerIPU3::freeBuffers(Camera *camera) data->ipa_->unmapBuffers(ids); ipaBuffers_.clear(); - data->imgu_->freeBuffers(); + imgu0_.freeBuffers(); return 0; } @@ -773,9 +772,18 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] const ControlLis IPU3CameraData *data = cameraData(camera); CIO2Device *cio2 = &data->cio2_; - ImgUDevice *imgu = data->imgu_; int ret; + imgu0_.input_->bufferReady.connect(&data->cio2_, + &CIO2Device::tryReturnBuffer); + imgu0_.output_->bufferReady.connect(data, + &IPU3CameraData::imguOutputBufferReady); + imgu0_.viewfinder_->bufferReady.connect(data, + &IPU3CameraData::imguOutputBufferReady); + imgu0_.param_->bufferReady.connect(data, + &IPU3CameraData::paramBufferReady); + imgu0_.stat_->bufferReady.connect(data, + &IPU3CameraData::statBufferReady); /* Disable test pattern mode on the sensor, if any. */ ret = cio2->sensor()->setTestPatternMode( controls::draft::TestPatternModeEnum::TestPatternModeOff); @@ -803,19 +811,24 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] const ControlLis if (ret) goto error; - ret = imgu->start(); + ret = imgu0_.start(); if (ret) goto error; return 0; error: - imgu->stop(); + imgu0_.stop(); cio2->stop(); data->ipa_->stop(); freeBuffers(camera); LOG(IPU3, Error) << "Failed to start camera " << camera->id(); + imgu0_.input_->bufferReady.disconnect(); + imgu0_.output_->bufferReady.disconnect(); + imgu0_.viewfinder_->bufferReady.disconnect(); + imgu0_.param_->bufferReady.disconnect(); + imgu0_.stat_->bufferReady.disconnect(); inUseCamera_ = nullptr; return ret; @@ -830,13 +843,19 @@ void PipelineHandlerIPU3::stopDevice(Camera *camera) data->ipa_->stop(); - ret |= data->imgu_->stop(); + ret |= imgu0_.stop(); ret |= data->cio2_.stop(); if (ret) LOG(IPU3, Warning) << "Failed to stop camera " << camera->id(); freeBuffers(camera); + data->imgu0_->input_->bufferReady.disconnect(); + data->imgu0_->output_->bufferReady.disconnect(); + data->imgu0_->viewfinder_->bufferReady.disconnect(); + data->imgu0_->param_->bufferReady.disconnect(); + data->imgu0_->stat_->bufferReady.disconnect(); + inUseCamera_ = nullptr; } @@ -1180,7 +1199,8 @@ int PipelineHandlerIPU3::registerCameras() * only, and assign imgu0 to the first one and imgu1 to the * second. */ - data->imgu_ = numCameras ? &imgu1_ : &imgu0_; + data->imgu0_ = &imgu0_; + data->imgu1_ = &imgu1_; /* * Connect video devices' 'bufferReady' signals to their @@ -1194,16 +1214,6 @@ int PipelineHandlerIPU3::registerCameras() &IPU3CameraData::cio2BufferReady); data->cio2_.bufferAvailable.connect( data.get(), &IPU3CameraData::queuePendingRequests); - data->imgu_->input_->bufferReady.connect(&data->cio2_, - &CIO2Device::tryReturnBuffer); - data->imgu_->output_->bufferReady.connect(data.get(), - &IPU3CameraData::imguOutputBufferReady); - data->imgu_->viewfinder_->bufferReady.connect(data.get(), - &IPU3CameraData::imguOutputBufferReady); - data->imgu_->param_->bufferReady.connect(data.get(), - &IPU3CameraData::paramBufferReady); - data->imgu_->stat_->bufferReady.connect(data.get(), - &IPU3CameraData::statBufferReady); /* Create and register the Camera instance. */ const std::string &cameraId = cio2->sensor()->id(); @@ -1296,14 +1306,14 @@ void IPU3CameraData::paramsBufferReady(unsigned int id) FrameBuffer *outbuffer = it.second; if (stream == &outStream_) - imgu_->output_->queueBuffer(outbuffer); + imgu0_->output_->queueBuffer(outbuffer); else if (stream == &vfStream_) - imgu_->viewfinder_->queueBuffer(outbuffer); + imgu0_->viewfinder_->queueBuffer(outbuffer); } - imgu_->param_->queueBuffer(info->paramBuffer); - imgu_->stat_->queueBuffer(info->statBuffer); - imgu_->input_->queueBuffer(info->rawBuffer); + imgu0_->param_->queueBuffer(info->paramBuffer); + imgu0_->stat_->queueBuffer(info->statBuffer); + imgu0_->input_->queueBuffer(info->rawBuffer); } void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata) From patchwork Thu May 12 10:32:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 15900 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 C5B98C326C for ; Thu, 12 May 2022 10:33:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7407E65663; Thu, 12 May 2022 12:33:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1652351593; bh=8EXAg82AdSpsCl53qJ1YTLjmuqrdevfnkMrtDo45H0w=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=TQo/eogZkquhMrQV3FkrK16aQyv2WoiU5/H3eHOe2vDFKSg1RGbobMSbSQGSvH8k3 2WIVUH4LxaNpMZ+ShcaurOr2sn9QYnaE1E/FLQk+lmnV9oGjENBSOfvyU2+vITObX5 xDl3UBTO6T8nJel7AguDPvXv3DKZ2wsUA7COI7G2p/uZ8jmJxNWUSN84OXhXptRbj9 50XJJ+LtMpxDg3nkvmTjm4fkHvuDAY43S+R8aQ0hZ7KkWJaWYPOGWZf906Dh5ISpNz e/ygFhmynFnOkghNz8vhJ6O7xRYZ/9CNOXFvShcwdLcwuIQusnk2ZEhQgHbrVMlqfw +6NjZjvuPKI3w== Received: from mail-pj1-x1032.google.com (mail-pj1-x1032.google.com [IPv6:2607:f8b0:4864:20::1032]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 525DF6565F for ; Thu, 12 May 2022 12:33:11 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="UCHZrqwP"; dkim-atps=neutral Received: by mail-pj1-x1032.google.com with SMTP id gj17-20020a17090b109100b001d8b390f77bso7441182pjb.1 for ; Thu, 12 May 2022 03:33:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=dZ83oghNle34XzMKsAViAcUAcF3HO4Rp6e5Vv7F90BI=; b=UCHZrqwPB3g98duyykennGiyK+cGQ8Zxu++Al8lcHkRaKGXY4bIWTEAUbVnJbTE8LL JtM84pXa9KliKF7wMGQPS2NCg70hZ/d40pUR8QjsigPNH0oDePTurxm4jtePbRO4bCr+ gQuxKx0VRUD+qf1du84wa+VAkOxVSlNYSo9MQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=dZ83oghNle34XzMKsAViAcUAcF3HO4Rp6e5Vv7F90BI=; b=S69nc3WO+j+0MSty8UjARHKVQMwTsDx2yy27308IhVypeMzM092J/46Bm6B5Miz3mE QkwO2LlriE0ZCE5keEBiD76F8WMcOz9zzF7eGcoFvNETFYlzE3EbmBuEHMGgDN/XI3Td zcdg6m/rSNrq4pPaXkxgcI90ZbZa+KmGSFbRtLTyCz3xvcUrAuLVr82jgnusq+yKRBWw eA57rh9rTYVwRrp4GnpVcVYDX6uLPFlmhHlYpW9dWZspjtCRY8x25Qk+R/jTMmgq0VOY qGeWPLutVWEIezKFTyc1uEunGDChESiHt5VJEk02hMCO/QE50BMcKCrZoUVx257ZtE5O 61lA== X-Gm-Message-State: AOAM531URiU1YHfmim8rYmN5EaT250Qbbd/WksEgGgFvwcqzyddcrR3r UUhY0o3Po++r5gUSOIzwaZVANwJukzCVeNVJ X-Google-Smtp-Source: ABdhPJxwJ4kMWi5LVGWffE3L139TDcMTaDnN1N0TWlR/2azoOZOXpgsCracV47bQliSytkuXnbYNlw== X-Received: by 2002:a17:90b:4a01:b0:1dc:b062:da0e with SMTP id kk1-20020a17090b4a0100b001dcb062da0emr10190358pjb.87.1652351589551; Thu, 12 May 2022 03:33:09 -0700 (PDT) Received: from chenghaoyang-low.c.googlers.com.com (174.71.80.34.bc.googleusercontent.com. [34.80.71.174]) by smtp.gmail.com with ESMTPSA id t19-20020a62d153000000b005087c23ad8dsm3402219pfl.0.2022.05.12.03.33.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 12 May 2022 03:33:09 -0700 (PDT) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 12 May 2022 10:32:54 +0000 Message-Id: <20220512103258.324339-5-chenghaoyang@google.com> X-Mailer: git-send-email 2.36.0.512.ge40c2bad7a-goog In-Reply-To: <20220512103258.324339-1-chenghaoyang@google.com> References: <20220512103258.324339-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 4/8] Add StillCapture stream and imgu1 param buffers 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: , X-Patchwork-Original-From: Harvey Yang via libcamera-devel From: Cheng-Hao Yang Reply-To: Harvey Yang Cc: Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Harvey Yang This patch adds the StillCapture stream and imgu1 param buffers, and the following patches will enable imgu1 to handle StillCapture stream specifically, when the imgu0 needs to handle video/preview streams. Signed-off-by: Harvey Yang --- src/libcamera/pipeline/ipu3/frames.cpp | 23 +++++++++++++++++++++-- src/libcamera/pipeline/ipu3/frames.h | 8 +++++++- src/libcamera/pipeline/ipu3/ipu3.cpp | 20 +++++++++++++++++++- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/frames.cpp b/src/libcamera/pipeline/ipu3/frames.cpp index a4c3477c..f9b705a5 100644 --- a/src/libcamera/pipeline/ipu3/frames.cpp +++ b/src/libcamera/pipeline/ipu3/frames.cpp @@ -23,7 +23,8 @@ IPU3Frames::IPU3Frames() } void IPU3Frames::init(const std::vector> ¶mBuffers, - const std::vector> &statBuffers) + const std::vector> &statBuffers, + const std::vector> &captureParamBuffers) { for (const std::unique_ptr &buffer : paramBuffers) availableParamBuffers_.push(buffer.get()); @@ -31,6 +32,9 @@ void IPU3Frames::init(const std::vector> ¶mBuff for (const std::unique_ptr &buffer : statBuffers) availableStatBuffers_.push(buffer.get()); + for (const std::unique_ptr &buffer : captureParamBuffers) + availableCaptureParamBuffers_.push(buffer.get()); + frameInfo_.clear(); } @@ -38,6 +42,7 @@ void IPU3Frames::clear() { availableParamBuffers_ = {}; availableStatBuffers_ = {}; + availableCaptureParamBuffers_ = {}; } IPU3Frames::Info *IPU3Frames::create(Request *request) @@ -54,14 +59,22 @@ IPU3Frames::Info *IPU3Frames::create(Request *request) return nullptr; } + if (availableCaptureParamBuffers_.empty()) { + LOG(IPU3, Debug) << "Capture parameters buffer underrun"; + return nullptr; + } + FrameBuffer *paramBuffer = availableParamBuffers_.front(); FrameBuffer *statBuffer = availableStatBuffers_.front(); + FrameBuffer *captureParamBuffer = availableCaptureParamBuffers_.front(); paramBuffer->_d()->setRequest(request); statBuffer->_d()->setRequest(request); + captureParamBuffer->_d()->setRequest(request); availableParamBuffers_.pop(); availableStatBuffers_.pop(); + availableCaptureParamBuffers_.pop(); /* \todo Remove the dynamic allocation of Info */ std::unique_ptr info = std::make_unique(); @@ -71,7 +84,9 @@ IPU3Frames::Info *IPU3Frames::create(Request *request) info->rawBuffer = nullptr; info->paramBuffer = paramBuffer; info->statBuffer = statBuffer; + info->captureParamBuffer = captureParamBuffer; info->paramDequeued = false; + info->captureParamDequeued = false; info->metadataProcessed = false; frameInfo_[id] = std::move(info); @@ -84,6 +99,7 @@ void IPU3Frames::remove(IPU3Frames::Info *info) /* Return params and stat buffer for reuse. */ availableParamBuffers_.push(info->paramBuffer); availableStatBuffers_.push(info->statBuffer); + availableCaptureParamBuffers_.push(info->captureParamBuffer); /* Delete the extended frame information. */ frameInfo_.erase(info->id); @@ -102,6 +118,9 @@ bool IPU3Frames::tryComplete(IPU3Frames::Info *info) if (!info->paramDequeued) return false; + if (!info->captureParamDequeued) + return false; + remove(info); bufferAvailable.emit(); @@ -131,7 +150,7 @@ IPU3Frames::Info *IPU3Frames::find(FrameBuffer *buffer) return info; if (info->rawBuffer == buffer || info->paramBuffer == buffer || - info->statBuffer == buffer) + info->statBuffer == buffer || info->captureParamBuffer == buffer) return info; } diff --git a/src/libcamera/pipeline/ipu3/frames.h b/src/libcamera/pipeline/ipu3/frames.h index 6e3cb915..8fcb8a14 100644 --- a/src/libcamera/pipeline/ipu3/frames.h +++ b/src/libcamera/pipeline/ipu3/frames.h @@ -36,16 +36,20 @@ public: FrameBuffer *paramBuffer; FrameBuffer *statBuffer; + FrameBuffer *captureParamBuffer; + ControlList effectiveSensorControls; bool paramDequeued; + bool captureParamDequeued; bool metadataProcessed; }; IPU3Frames(); void init(const std::vector> ¶mBuffers, - const std::vector> &statBuffers); + const std::vector> &statBuffers, + const std::vector> &captureParamBuffers); void clear(); Info *create(Request *request); @@ -61,6 +65,8 @@ private: std::queue availableParamBuffers_; std::queue availableStatBuffers_; + std::queue availableCaptureParamBuffers_; + std::map> frameInfo_; }; diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 5dd13c41..b635976b 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -70,6 +70,7 @@ public: Stream outStream_; Stream vfStream_; Stream rawStream_; + Stream outCaptureStream_; Rectangle cropRegion_; bool supportsFlips_; @@ -696,6 +697,8 @@ int PipelineHandlerIPU3::exportFrameBuffers(Camera *camera, Stream *stream, return imgu0_.viewfinder_->exportBuffers(count, buffers); else if (stream == &data->rawStream_) return data->cio2_.exportBuffers(count, buffers); + else if (stream == &data->outCaptureStream_) + return imgu1_.output_->exportBuffers(count, buffers); return -EINVAL; } @@ -718,11 +721,17 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera) data->outStream_.configuration().bufferCount, data->vfStream_.configuration().bufferCount, data->rawStream_.configuration().bufferCount, + data->outCaptureStream_.configuration().bufferCount, }); ret = imgu0_.allocateBuffers(bufferCount); if (ret < 0) return ret; + ret = imgu1_.allocateBuffers(bufferCount); + if (ret < 0) { + imgu0_.freeBuffers(); + return ret; + } /* Map buffers to the IPA. */ unsigned int ipaBufferId = 1; @@ -737,9 +746,14 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera) ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes()); } + for (const std::unique_ptr &buffer : imgu1_.paramBuffers_) { + buffer->setCookie(ipaBufferId++); + ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes()); + } + data->ipa_->mapBuffers(ipaBuffers_); - data->frameInfos_.init(imgu0_.paramBuffers_, imgu0_.statBuffers_); + data->frameInfos_.init(imgu0_.paramBuffers_, imgu0_.statBuffers_, imgu1_.paramBuffers_); data->frameInfos_.bufferAvailable.connect( data, &IPU3CameraData::queuePendingRequests); @@ -760,6 +774,7 @@ int PipelineHandlerIPU3::freeBuffers(Camera *camera) ipaBuffers_.clear(); imgu0_.freeBuffers(); + imgu1_.freeBuffers(); return 0; } @@ -1139,6 +1154,7 @@ int PipelineHandlerIPU3::registerCameras() &data->outStream_, &data->vfStream_, &data->rawStream_, + &data->outCaptureStream_, }; CIO2Device *cio2 = &data->cio2_; @@ -1314,6 +1330,8 @@ void IPU3CameraData::paramsBufferReady(unsigned int id) imgu0_->param_->queueBuffer(info->paramBuffer); imgu0_->stat_->queueBuffer(info->statBuffer); imgu0_->input_->queueBuffer(info->rawBuffer); + + info->captureParamDequeued = true; } void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata) From patchwork Thu May 12 10:32:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 15901 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 482E8C3256 for ; Thu, 12 May 2022 10:33:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EB8B365669; Thu, 12 May 2022 12:33:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1652351594; bh=NmvPGRWZ8BHkKJ+CL/GqZwQR9gt2UjFZgPCTRdQ7tY0=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=SJmaAAqcprj8EEBPop/zbjeKA9GIEY0LMJOnYtasTp8QPmjOvcqTPMXCvt7NW5D2/ QOX1BOFjqNnpNm1VEe0lyRrYrUXe1Wnz749BbwyYNmBxPE5XkuVsXv5Xmb1+KIPTUk 7RyrYlg7Wu2rxzVsuCjgw7Mrup9p5XGoDfNcyL78I6NqxyNNG0jdiQCDEnfBZnhkPA hklxmyHIuDEoAAi1k3XrnqvBTMwHUIOf3a7EcuKyVuHOVEjQAEQfVxFiLA9Lg3npkh ukgVUycyBU1kk2M9bA+9Cw1abv55U7Iw0cfds/ornuuLSgwy7DEPZm9vCNKHnbBDvl R0l2W8k65pASw== Received: from mail-pl1-x630.google.com (mail-pl1-x630.google.com [IPv6:2607:f8b0:4864:20::630]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F2EEB65656 for ; Thu, 12 May 2022 12:33:12 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="Y2L6SgJS"; dkim-atps=neutral Received: by mail-pl1-x630.google.com with SMTP id d22so4452922plr.9 for ; Thu, 12 May 2022 03:33:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=wq1C41Z7au0ZywRuZwrAMRj2QMMsSgjjchnT4sVEoaA=; b=Y2L6SgJSWArSGmqA51+l0y0KLmtXa7GAPxQ6yj2rtu9xaH/RJpbbIqF+zWoat7Vrkz Lyuc1WX6f63xXOW5mdFZR2ckI+VdJAAsYiK9uGVdlP3QGqbKh/xn4Nv40EggBz00lND/ 48E93/Gc5AsUYMdZR0h30pHKN5g/BiMvxattI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wq1C41Z7au0ZywRuZwrAMRj2QMMsSgjjchnT4sVEoaA=; b=vX7czXHhl9Dw2BL/NGY9YB7pvDbu+5jtP5kAzC+xTmPGxGVGWuE8G6vn2PCwDNOnoC d2PO8dzJU20ZX6LdTyiBQJzUaH5jt8n/73/HsSqYo6e6XHVTN5+5B2Wc2XhvMzawbcWQ kfGdghspLXREk4qZD5+xn0JUHbsx+fkXKl4xGFL0wHFBBTUnN71yPEigkA5eiEHMHYbR 76XddIuwmEVR4rqcNNgaqcxTcqSbKPNJdkXOlpxNX4c4ZMuRyI3rQcePlpbgyDvE3p9p YcDl4yZz7Q3oicMMc5hzezxRvISmsUTBR1PJ94jKR1vxzoK1SiWHziCxB3SkMrvDSIb0 ar0w== X-Gm-Message-State: AOAM531oHh33p8hXoce2ZLUjoL2XJYDJa6ZLuHstqrkE3/k/u4zvOiK5 weHvdZALhwUdUiU85/dSiuEIxmsDB8Xmwn/Y X-Google-Smtp-Source: ABdhPJx1t5pUAcmb8Dg1BoKKPS7nu+3vq4LBSMGRwaY4SSuTHaGGrtA9Hba2xJNlkI5Gk4sNuIidVA== X-Received: by 2002:a17:90b:33cd:b0:1dc:c9b9:2a6e with SMTP id lk13-20020a17090b33cd00b001dcc9b92a6emr10152025pjb.86.1652351591102; Thu, 12 May 2022 03:33:11 -0700 (PDT) Received: from chenghaoyang-low.c.googlers.com.com (174.71.80.34.bc.googleusercontent.com. [34.80.71.174]) by smtp.gmail.com with ESMTPSA id t19-20020a62d153000000b005087c23ad8dsm3402219pfl.0.2022.05.12.03.33.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 12 May 2022 03:33:10 -0700 (PDT) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 12 May 2022 10:32:55 +0000 Message-Id: <20220512103258.324339-6-chenghaoyang@google.com> X-Mailer: git-send-email 2.36.0.512.ge40c2bad7a-goog In-Reply-To: <20220512103258.324339-1-chenghaoyang@google.com> References: <20220512103258.324339-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 5/8] Update IPAIPU3Interface::fillParamsBuffer with captureBufferId 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: , X-Patchwork-Original-From: Harvey Yang via libcamera-devel From: Cheng-Hao Yang Reply-To: Harvey Yang Cc: Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Harvey Yang This patch updates the ipa interface |IPAIPU3Interface::fillParamsBuffer| with additional |captureBufferId| to fill the param buffer for StillCapture as well. Signed-off-by: Harvey Yang --- include/libcamera/ipa/ipu3.mojom | 2 +- src/ipa/ipu3/ipu3.cpp | 19 ++++++++++++++++--- src/libcamera/pipeline/ipu3/ipu3.cpp | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/include/libcamera/ipa/ipu3.mojom b/include/libcamera/ipa/ipu3.mojom index d1b1c6b8..d94c344e 100644 --- a/include/libcamera/ipa/ipu3.mojom +++ b/include/libcamera/ipa/ipu3.mojom @@ -31,7 +31,7 @@ interface IPAIPU3Interface { unmapBuffers(array ids); [async] queueRequest(uint32 frame, libcamera.ControlList controls); - [async] fillParamsBuffer(uint32 frame, uint32 bufferId); + [async] fillParamsBuffer(uint32 frame, uint32 bufferId, uint32 captureBufferId); [async] processStatsBuffer(uint32 frame, int64 frameTimestamp, uint32 bufferId, libcamera.ControlList sensorControls); }; diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index dd6cfd79..b0cc8cd7 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -146,7 +146,7 @@ public: void unmapBuffers(const std::vector &ids) override; void queueRequest(const uint32_t frame, const ControlList &controls) override; - void fillParamsBuffer(const uint32_t frame, const uint32_t bufferId) override; + void fillParamsBuffer(const uint32_t frame, const uint32_t bufferId, const uint32_t captureBufferId) override; void processStatsBuffer(const uint32_t frame, const int64_t frameTimestamp, const uint32_t bufferId, const ControlList &sensorControls) override; @@ -508,12 +508,13 @@ void IPAIPU3::unmapBuffers(const std::vector &ids) /** * \brief Fill and return a buffer with ISP processing parameters for a frame * \param[in] frame The frame number - * \param[in] bufferId ID of the parameter buffer to fill + * \param[in] bufferId ID of the video parameter buffer to fill + * \param[in] captureBufferId ID of the capture parameter buffer to fill * * Algorithms are expected to fill the IPU3 parameter buffer for the next * frame given their most recent processing of the ImgU statistics. */ -void IPAIPU3::fillParamsBuffer(const uint32_t frame, const uint32_t bufferId) +void IPAIPU3::fillParamsBuffer(const uint32_t frame, const uint32_t bufferId, const uint32_t captureBufferId) { auto it = buffers_.find(bufferId); if (it == buffers_.end()) { @@ -536,6 +537,18 @@ void IPAIPU3::fillParamsBuffer(const uint32_t frame, const uint32_t bufferId) */ params->use = {}; + for (auto const &algo : algorithms_) + algo->prepare(context_, params); + + // TODO: use different algorithms to set StillCapture params. + it = buffers_.find(captureBufferId); + if (it == buffers_.end()) { + LOG(IPAIPU3, Error) << "Could not find capture param buffer!"; + return; + } + mem = it->second.planes()[0]; + params = reinterpret_cast(mem.data()); + params->use = {}; for (auto const &algo : algorithms_) algo->prepare(context_, params); diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index b635976b..8ce1968f 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -1420,7 +1420,7 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer) if (request->findBuffer(&rawStream_)) pipe()->completeBuffer(request, buffer); - ipa_->fillParamsBuffer(info->id, info->paramBuffer->cookie()); + ipa_->fillParamsBuffer(info->id, info->paramBuffer->cookie(), info->captureParamBuffer->cookie()); } void IPU3CameraData::paramBufferReady(FrameBuffer *buffer) From patchwork Thu May 12 10:32:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 15902 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 D0ACFC326C for ; Thu, 12 May 2022 10:33:16 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 71E2665670; Thu, 12 May 2022 12:33:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1652351596; bh=VP2nw55uW/QB4dezhVhvnuEfHpreQgLzYfYwy7PCD+Y=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=xNICuhVe85cswJo9sdyHYBoEAgOkZut7WvSVtF9/4WM/h9RYsfkuJbrsLkBx5yQJ0 xj6sTPfqxH8o1+Ko40d4k+ghItca1YRng3JdITKZAgpi/Wse2tRLNF4GjLFuC+1hQR x5tAcrIkIqtj8oHFGSFTOVDcjeLNUmTMthGhVf8oR//sniRB00sv3iDl7HMTLp2KOB AQhVrg9cHdrpfG35A4I39/ihiHxr6r2c7kvRL6alIo9ONWo93W7hVRbsqvyUIvewD0 WJNSVl1HP45OKObnDNElh4+FJTcI0CzLbSfPaQPemntbv/GwlKMujoJved7jn+LI8o RveZgCQcsRAbQ== Received: from mail-pl1-x634.google.com (mail-pl1-x634.google.com [IPv6:2607:f8b0:4864:20::634]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DB87165657 for ; Thu, 12 May 2022 12:33:14 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="T6OhWMWH"; dkim-atps=neutral Received: by mail-pl1-x634.google.com with SMTP id x18so4467279plg.6 for ; Thu, 12 May 2022 03:33:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=DUzZlYpdbMeE74ukQP/CyVaVtD+Vet5FhfkFoC2n4bw=; b=T6OhWMWHzJy59BplgHZvi8xJb7uaLRO/FrrHmPm4keEtmaYu1p7v/oUofse811Y4MJ ZCY2aNra2dC6Ss//tXiXu87eX4nOqJKPcw2c04QdaCSzacZp4rTLSDwrryY8Nea/v3yT TuryYsDw4XBuQ6rpFs5Fukka76pKfsGVrN5xc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=DUzZlYpdbMeE74ukQP/CyVaVtD+Vet5FhfkFoC2n4bw=; b=VedINhCOthJ/dmsA+SU3UfbWYdnffRikJ9UH9jVD9xPrBm/EToMZOArqFjSPfEkQXW /xBbuzMZx1MTukc0f86lbPe15Gf+pAvxWytOKH0v2B5H2xk0zp7XgIsMO5zTT1ScVdAF K8aFojhWTT/tdcNVuBMoj2BpbKy+a+Kr4z9fYSavO713cgwKlvn/cCl93euu+AbKSxP3 HeCkXVVu0UTO6+3NVQlEq2PFq28qMvCTcb3A8smVU2fw4BeXQp34u1FNkKMhv2wK/uqR 6QKm7fh/yn83G+KU3W1iBYFrbzPxScZhluHdXE9afdPpWpX6ktVO25rB+0eqhgvlI2W3 uHQA== X-Gm-Message-State: AOAM531I4LDp4s/9L0ZXZ7Vnazd2pGKncaI9x72ka3ESZKUc7iaOvBfS 6kj2j3bofCQT8axkSrjxkOzepvRJf6gbOQ6a X-Google-Smtp-Source: ABdhPJzPgxkhewf5JekBqacrDARL9eroLDLOkmyFhMWJfaA/W3DWASosYOBBjK1rDm08kltZ6ScOsQ== X-Received: by 2002:a17:90a:9483:b0:1dc:5fb2:9b89 with SMTP id s3-20020a17090a948300b001dc5fb29b89mr9998497pjo.235.1652351592975; Thu, 12 May 2022 03:33:12 -0700 (PDT) Received: from chenghaoyang-low.c.googlers.com.com (174.71.80.34.bc.googleusercontent.com. [34.80.71.174]) by smtp.gmail.com with ESMTPSA id t19-20020a62d153000000b005087c23ad8dsm3402219pfl.0.2022.05.12.03.33.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 12 May 2022 03:33:12 -0700 (PDT) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 12 May 2022 10:32:56 +0000 Message-Id: <20220512103258.324339-7-chenghaoyang@google.com> X-Mailer: git-send-email 2.36.0.512.ge40c2bad7a-goog In-Reply-To: <20220512103258.324339-1-chenghaoyang@google.com> References: <20220512103258.324339-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 6/8] Configure imgu1 when necessary 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: , X-Patchwork-Original-From: Harvey Yang via libcamera-devel From: Cheng-Hao Yang Reply-To: Harvey Yang Cc: Harvey Yang , Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" This patch configure and setup imgu1 when still capture and other streams are enabled. If only still capture is enabled, imgu0 is still being used with IPU3PipeModeStillCapture. Still capture stream will be enabled in the following patches though. Signed-off-by: Harvey Yang --- src/libcamera/pipeline/ipu3/ipu3.cpp | 179 +++++++++++++++++++++++---- 1 file changed, 155 insertions(+), 24 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 8ce1968f..9498b1b0 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -55,9 +55,11 @@ public: int loadIPA(); + void tryReturnBuffer(FrameBuffer *buffer); void imguOutputBufferReady(FrameBuffer *buffer); void cio2BufferReady(FrameBuffer *buffer); void paramBufferReady(FrameBuffer *buffer); + void captureParamBufferReady(FrameBuffer *buffer); void statBufferReady(FrameBuffer *buffer); void queuePendingRequests(); void cancelPendingRequests(); @@ -93,6 +95,8 @@ private: void paramsBufferReady(unsigned int id); void setSensorControls(unsigned int id, const ControlList &sensorControls, const ControlList &lensControls); + + std::map inputReturnCounters; }; class IPU3CameraConfiguration : public CameraConfiguration @@ -106,11 +110,14 @@ public: Status validate() override; const StreamConfiguration &cio2Format() const { return cio2Configuration_; } - const ImgUDevice::PipeConfig imguConfig() const { return pipeConfig_; } + const ImgUDevice::PipeConfig imguConfig0() const { return pipeConfig0_; } + const ImgUDevice::PipeConfig imguConfig1() const { return pipeConfig1_; } /* Cache the combinedTransform_ that will be applied to the sensor */ Transform combinedTransform_; + bool onlyStillCapture_ = false; + private: /* * The IPU3CameraData instance is guaranteed to be valid as long as the @@ -120,7 +127,8 @@ private: const IPU3CameraData *data_; StreamConfiguration cio2Configuration_; - ImgUDevice::PipeConfig pipeConfig_; + ImgUDevice::PipeConfig pipeConfig0_; + ImgUDevice::PipeConfig pipeConfig1_; }; class PipelineHandlerIPU3 : public PipelineHandler @@ -168,6 +176,9 @@ private: MediaDevice *cio2MediaDev_; MediaDevice *imguMediaDev_; + bool onlyStillCapture_ = false; + bool useImgu1_ = false; + Camera *inUseCamera_ = nullptr; std::vector ipaBuffers_; @@ -408,8 +419,8 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() /* Only compute the ImgU configuration if a YUV stream has been requested. */ if (yuvCount) { - pipeConfig_ = data_->imgu0_->calculatePipeConfig(&pipe); - if (pipeConfig_.isNull()) { + pipeConfig0_ = data_->imgu0_->calculatePipeConfig(&pipe); + if (pipeConfig0_.isNull()) { LOG(IPU3, Error) << "Failed to calculate pipe configuration: " << "unsupported resolutions."; return Invalid; @@ -519,8 +530,14 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) IPU3CameraData *data = cameraData(camera); Stream *outStream = &data->outStream_; Stream *vfStream = &data->vfStream_; + Stream *outCaptureStream = &data->outCaptureStream_; CIO2Device *cio2 = &data->cio2_; V4L2DeviceFormat outputFormat; + + onlyStillCapture_ = config->onlyStillCapture_; + ImgUDevice::PipeConfig imguConfig1 = config->imguConfig1(); + useImgu1_ = !imguConfig1.isNull(); + int ret; /* @@ -565,6 +582,12 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) if (ret) return ret; + if (useImgu1_) { + ret = imgu1_.enableLinks(true); + if (ret) + return ret; + } + /* * Pass the requested stream size to the CIO2 unit and get back the * adjusted format to be propagated to the ImgU output devices. @@ -607,14 +630,20 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) * stream has been requested: return here to skip the ImgU configuration * part. */ - ImgUDevice::PipeConfig imguConfig = config->imguConfig(); - if (imguConfig.isNull()) + ImgUDevice::PipeConfig imguConfig0 = config->imguConfig0(); + if (imguConfig0.isNull()) return 0; - ret = imgu0_.configure(imguConfig, &cio2Format); + ret = imgu0_.configure(imguConfig0, &cio2Format); if (ret) return ret; + if (useImgu1_) { + ret = imgu1_.configure(imguConfig1, &cio2Format); + if (ret) + return ret; + } + /* Apply the format to the configured streams output devices. */ StreamConfiguration *mainCfg = nullptr; StreamConfiguration *vfCfg = nullptr; @@ -633,6 +662,15 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) ret = imgu0_.configureViewfinder(cfg, &outputFormat); if (ret) return ret; + } else if (stream == outCaptureStream) { + ASSERT(useImgu1_); + ret = imgu1_.configureOutput(cfg, &outputFormat); + if (ret) + return ret; + + ret = imgu1_.configureViewfinder(cfg, &outputFormat); + if (ret) + return ret; } } @@ -648,22 +686,35 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) } /* Apply the "pipe_mode" control to the ImgU subdevice. */ - ControlList ctrls(imgu0_.imgu_->controls()); + ControlList ctrls0(imgu0_.imgu_->controls()); /* * Set the ImgU pipe mode to 'Video' unconditionally to have statistics * generated. - * - * \todo Figure out what the 'Still Capture' mode is meant for, and use - * it accordingly. */ - ctrls.set(V4L2_CID_IPU3_PIPE_MODE, - static_cast(IPU3PipeModeVideo)); - ret = imgu0_.imgu_->setControls(&ctrls); + ctrls0.set(V4L2_CID_IPU3_PIPE_MODE, + static_cast(onlyStillCapture_ ? + IPU3PipeModeStillCapture : IPU3PipeModeVideo)); + ret = imgu0_.imgu_->setControls(&ctrls0); if (ret) { LOG(IPU3, Error) << "Unable to set pipe_mode control"; return ret; } + if (useImgu1_) { + ControlList ctrls1(imgu1_.imgu_->controls()); + /* + * \todo Figure out what the 'Still Capture' mode is meant for, + * and use it accordingly. + */ + ctrls1.set(V4L2_CID_IPU3_PIPE_MODE, + static_cast(IPU3PipeModeStillCapture)); + ret = imgu1_.imgu_->setControls(&ctrls1); + if (ret) { + LOG(IPU3, Error) << "Unable to set pipe_mode control"; + return ret; + } + } + ipa::ipu3::IPAConfigInfo configInfo; configInfo.sensorControls = data->cio2_.sensor()->controls(); @@ -672,8 +723,8 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) configInfo.lensControls = lens->controls(); configInfo.sensorInfo = sensorInfo; - configInfo.bdsOutputSize = config->imguConfig().bds; - configInfo.iif = config->imguConfig().iif; + configInfo.bdsOutputSize = config->imguConfig0().bds; + configInfo.iif = config->imguConfig0().iif; ret = data->ipa_->configure(configInfo, &data->ipaControls_); if (ret) { @@ -789,8 +840,8 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] const ControlLis CIO2Device *cio2 = &data->cio2_; int ret; - imgu0_.input_->bufferReady.connect(&data->cio2_, - &CIO2Device::tryReturnBuffer); + imgu0_.input_->bufferReady.connect(data, + &IPU3CameraData::tryReturnBuffer); imgu0_.output_->bufferReady.connect(data, &IPU3CameraData::imguOutputBufferReady); imgu0_.viewfinder_->bufferReady.connect(data, @@ -799,6 +850,16 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] const ControlLis &IPU3CameraData::paramBufferReady); imgu0_.stat_->bufferReady.connect(data, &IPU3CameraData::statBufferReady); + + if (useImgu1_) { + imgu1_.input_->bufferReady.connect(data, + &IPU3CameraData::tryReturnBuffer); + imgu1_.output_->bufferReady.connect(data, + &IPU3CameraData::imguOutputBufferReady); + imgu1_.param_->bufferReady.connect(data, + &IPU3CameraData::captureParamBufferReady); + } + /* Disable test pattern mode on the sensor, if any. */ ret = cio2->sensor()->setTestPatternMode( controls::draft::TestPatternModeEnum::TestPatternModeOff); @@ -830,10 +891,17 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] const ControlLis if (ret) goto error; + if (useImgu1_) { + ret = imgu1_.start(); + if (ret) + goto error; + } + return 0; error: imgu0_.stop(); + imgu1_.stop(); cio2->stop(); data->ipa_->stop(); freeBuffers(camera); @@ -844,6 +912,12 @@ error: imgu0_.viewfinder_->bufferReady.disconnect(); imgu0_.param_->bufferReady.disconnect(); imgu0_.stat_->bufferReady.disconnect(); + imgu1_.input_->bufferReady.disconnect(); + imgu1_.output_->bufferReady.disconnect(); + imgu1_.param_->bufferReady.disconnect(); + + onlyStillCapture_ = false; + useImgu1_ = false; inUseCamera_ = nullptr; return ret; @@ -859,6 +933,7 @@ void PipelineHandlerIPU3::stopDevice(Camera *camera) data->ipa_->stop(); ret |= imgu0_.stop(); + ret |= imgu1_.stop(); ret |= data->cio2_.stop(); if (ret) LOG(IPU3, Warning) << "Failed to stop camera " << camera->id(); @@ -870,7 +945,12 @@ void PipelineHandlerIPU3::stopDevice(Camera *camera) data->imgu0_->viewfinder_->bufferReady.disconnect(); data->imgu0_->param_->bufferReady.disconnect(); data->imgu0_->stat_->bufferReady.disconnect(); + data->imgu1_->input_->bufferReady.disconnect(); + data->imgu1_->output_->bufferReady.disconnect(); + data->imgu1_->param_->bufferReady.disconnect(); + onlyStillCapture_ = false; + useImgu1_ = false; inUseCamera_ = nullptr; } @@ -1316,22 +1396,45 @@ void IPU3CameraData::paramsBufferReady(unsigned int id) if (!info) return; + bool hasYuv = false; + bool hasCapture = false; /* Queue all buffers from the request aimed for the ImgU. */ for (auto it : info->request->buffers()) { const Stream *stream = it.first; FrameBuffer *outbuffer = it.second; - if (stream == &outStream_) + if (stream == &outStream_) { + hasYuv = true; imgu0_->output_->queueBuffer(outbuffer); - else if (stream == &vfStream_) + } else if (stream == &vfStream_) { + hasYuv = true; imgu0_->viewfinder_->queueBuffer(outbuffer); + } else if (stream == &outCaptureStream_) { + hasCapture = true; + + imgu1_->output_->queueBuffer(outbuffer); + } } - imgu0_->param_->queueBuffer(info->paramBuffer); - imgu0_->stat_->queueBuffer(info->statBuffer); - imgu0_->input_->queueBuffer(info->rawBuffer); + if (hasYuv) { + inputReturnCounters[info->rawBuffer] += 1; - info->captureParamDequeued = true; + imgu0_->param_->queueBuffer(info->paramBuffer); + imgu0_->stat_->queueBuffer(info->statBuffer); + imgu0_->input_->queueBuffer(info->rawBuffer); + } else { + info->paramDequeued = true; + info->metadataProcessed = true; + } + + if (hasCapture) { + inputReturnCounters[info->rawBuffer] += 1; + + imgu1_->param_->queueBuffer(info->captureParamBuffer); + imgu1_->input_->queueBuffer(info->rawBuffer); + } else { + info->captureParamDequeued = true; + } } void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata) @@ -1352,6 +1455,14 @@ void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata) * Buffer Ready slots */ +void IPU3CameraData::tryReturnBuffer(FrameBuffer *buffer) +{ + if (--inputReturnCounters[buffer] == 0) { + inputReturnCounters.erase(buffer); + cio2_.tryReturnBuffer(buffer); + } +} + /** * \brief Handle buffers completion at the ImgU output * \param[in] buffer The completed buffer @@ -1443,6 +1554,26 @@ void IPU3CameraData::paramBufferReady(FrameBuffer *buffer) pipe()->completeRequest(request); } +void IPU3CameraData::captureParamBufferReady(FrameBuffer *buffer) +{ + IPU3Frames::Info *info = frameInfos_.find(buffer); + if (!info) + return; + + info->captureParamDequeued = true; + + /* + * tryComplete() will delete info if it completes the IPU3Frame. + * In that event, we must have obtained the Request before hand. + * + * \todo Improve the FrameInfo API to avoid this type of issue + */ + Request *request = info->request; + + if (frameInfos_.tryComplete(info)) + pipe()->completeRequest(request); +} + void IPU3CameraData::statBufferReady(FrameBuffer *buffer) { IPU3Frames::Info *info = frameInfos_.find(buffer); From patchwork Thu May 12 10:32:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 15903 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 D54B0C3256 for ; Thu, 12 May 2022 10:33:18 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 78BEA65657; Thu, 12 May 2022 12:33:18 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1652351598; bh=gCQstSjvJGwHXaHOtpruSN974DmXKSWgDVgsIcbWObM=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=QJkaXTUlmnhT7pJQ9MQBQAa5JEhY9JAxWOydprmN6elcW/Pt0r42dktTj+/8b1z6Y P3gk02HRhMBeJLUHf9tWfZXMuAyuGmjDMDZGSIx9JJRBIaEly2c4MbVJCdgJqQKuO4 RzFcbgSA0zBMfk6Q2d/E/dwyx7T0z6Y+0w+W0UfLT2CR0bFdQ9qIRUvSPw+XL6c4F9 X0DEx64pNlVt13JdMDE5OcDWtDSLq8CPjmAXi9GfIRA+TSz25gUa2/LhDJ6xG8oXeB VYNjK5aI9S23NvgxoteAH34U2r8nlaT9y8FQpeRA4Tvi/FdHQhR/kDnw7cwVUluGEY IksFIKlwm2SeA== Received: from mail-pg1-x52f.google.com (mail-pg1-x52f.google.com [IPv6:2607:f8b0:4864:20::52f]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DE2CF65656 for ; Thu, 12 May 2022 12:33:16 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="Z6iwdeDj"; dkim-atps=neutral Received: by mail-pg1-x52f.google.com with SMTP id 31so4206527pgp.8 for ; Thu, 12 May 2022 03:33:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xiU6As+WxCHaLY/jIx5QcwNyTIeEOCwcYi0xBHtZjc8=; b=Z6iwdeDj4LGvMxWwAwAdatiBlkL/Tkh8AWtHfkzxHfxYcNyVid4jJvCnB3467RAXYp b6wvDm5a8jJokQQRshX+/bRggU/pdsxZ8NVacHHI8uoFwvKMuz/Vs2ojqyVDaHfUGAyI cliuW2RDyhB1Xo3e5Tb6ga3QgKsEL1v3GzJP0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xiU6As+WxCHaLY/jIx5QcwNyTIeEOCwcYi0xBHtZjc8=; b=pM5J4vpby9nkqRrnDYO54mYPxdRlHRn//euXznY4+wvhVyVqc3LwB5SpX/SqRpKZm4 YF+Pto4V3o604iHtxIvVCCVHg++XLz1cEgwm5d+z1EgWpl3B9A6P/bQECOBqjHIrOoe5 O/UWs/chs8obf3fkSeFW7Jguy+UWU+J3hvWESBE9mL/XwnsjDbbX+3UT/Z/YTmyQOaCx KTqoRKoBpTiZnucJOVFmUFY0SKolZ4R0uDa73OZH6YHrkDaBCFEMLSdYuvYnSWZpYT6s qy9UmeWjfRJXGVCTyy84A+rueHWPZ/cBgxcGrDP227288JqcCnbvtZM+4IFOs+Sx8RdC MbUw== X-Gm-Message-State: AOAM5329GSbEZOwkFbuyKyy+QuVi8uVIj77/nUMJ7DaSoABZRTMAij51 YH2yCl3KJzZOgrcgY1Mu925Ke2yLpoHbD87S X-Google-Smtp-Source: ABdhPJy2ShlBnvl7e4feG4KJLkasRLVIV3Vlt+L6FWqrLiV+3SkSTgObLq5NGAHH5hG2C2G2x7IO8g== X-Received: by 2002:a63:dc42:0:b0:3c5:e187:572 with SMTP id f2-20020a63dc42000000b003c5e1870572mr24829895pgj.82.1652351595016; Thu, 12 May 2022 03:33:15 -0700 (PDT) Received: from chenghaoyang-low.c.googlers.com.com (174.71.80.34.bc.googleusercontent.com. [34.80.71.174]) by smtp.gmail.com with ESMTPSA id t19-20020a62d153000000b005087c23ad8dsm3402219pfl.0.2022.05.12.03.33.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 12 May 2022 03:33:14 -0700 (PDT) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 12 May 2022 10:32:57 +0000 Message-Id: <20220512103258.324339-8-chenghaoyang@google.com> X-Mailer: git-send-email 2.36.0.512.ge40c2bad7a-goog In-Reply-To: <20220512103258.324339-1-chenghaoyang@google.com> References: <20220512103258.324339-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 7/8] Assign |outCaptureStream| to StillCapture configuration 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: , X-Patchwork-Original-From: Harvey Yang via libcamera-devel From: Cheng-Hao Yang Reply-To: Harvey Yang Cc: Harvey Yang , Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" When StillCapture and other non-raw configurations are requested, assigns |outCaptureStream| instead of |outStream| to the StillCapture configuration. Signed-off-by: Harvey Yang --- src/libcamera/pipeline/ipu3/ipu3.cpp | 51 +++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 9498b1b0..94aeebf3 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -257,8 +257,10 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() * \todo Clarify the IF and BDS margins requirements. */ unsigned int rawCount = 0; - unsigned int yuvCount = 0; + unsigned int videoCount = 0; + unsigned int stillCount = 0; Size maxYuvSize; + Size maxVideoSize; Size rawSize; for (const StreamConfiguration &cfg : config_) { @@ -267,16 +269,30 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) { rawCount++; rawSize.expandTo(cfg.size); + } else if (cfg.streamRole == StreamRole::StillCapture) { + if (stillCount != 0) + return Invalid; + + stillCount++; + maxYuvSize.expandTo(cfg.size); } else { - yuvCount++; + videoCount++; maxYuvSize.expandTo(cfg.size); + maxVideoSize.expandTo(cfg.size); } } - if (rawCount > 1 || yuvCount > 2) { + if (videoCount == 0 && stillCount == 1) { + stillCount = 0; + videoCount = 1; + onlyStillCapture_ = true; + maxVideoSize.expandTo(maxYuvSize); + } + + if (rawCount > 1 || videoCount > 2) { LOG(IPU3, Debug) << "Camera configuration not supported"; return Invalid; - } else if (rawCount && !yuvCount) { + } else if (rawCount && !stillCount && !videoCount) { /* * Disallow raw-only camera configuration. Currently, ImgU does * not get configured for raw-only streams and has early return @@ -319,6 +335,9 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() ImgUDevice::Pipe pipe{}; pipe.input = cio2Configuration_.size; + ImgUDevice::Pipe pipe1{}; + pipe1.input = cio2Configuration_.size; + /* * Adjust the configurations if needed and assign streams while * iterating them. @@ -383,18 +402,34 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() cfg->stride = info.stride(cfg->size.width, 0, 1); cfg->frameSize = info.frameSize(cfg->size, 1); + if (stillCount == 1 && cfg->streamRole == StreamRole::StillCapture) { + LOG(IPU3, Debug) << "Assigned " + << cfg->toString() + << " to the imgu1 main output"; + cfg->setStream(const_cast(&data_->outCaptureStream_)); + + pipe1.main = cfg->size; + pipe1.viewfinder = pipe1.main; + + pipeConfig1_ = data_->imgu1_->calculatePipeConfig(&pipe1); + if (pipeConfig1_.isNull()) { + LOG(IPU3, Error) << "Failed to calculate pipe configuration: " + << "unsupported resolutions."; + return Invalid; + } /* * Use the main output stream in case only one stream is * requested or if the current configuration is the one * with the maximum YUV output size. */ - if (mainOutputAvailable && - (originalCfg.size == maxYuvSize || yuvCount == 1)) { + } else if (mainOutputAvailable && + (originalCfg.size == maxVideoSize || + videoCount == 1)) { cfg->setStream(const_cast(&data_->outStream_)); mainOutputAvailable = false; pipe.main = cfg->size; - if (yuvCount == 1) + if (videoCount == 1) pipe.viewfinder = pipe.main; LOG(IPU3, Debug) << "Assigned " << cfg->toString() @@ -418,7 +453,7 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() } /* Only compute the ImgU configuration if a YUV stream has been requested. */ - if (yuvCount) { + if (videoCount) { pipeConfig0_ = data_->imgu0_->calculatePipeConfig(&pipe); if (pipeConfig0_.isNull()) { LOG(IPU3, Error) << "Failed to calculate pipe configuration: " From patchwork Thu May 12 10:32:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 15904 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 367FCC3256 for ; Thu, 12 May 2022 10:33:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id F1B2C65664; Thu, 12 May 2022 12:33:20 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1652351601; bh=acJunBReIxo39VWFgDP8qmaBHsVlPZCUe1Y3ALtmwnA=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=OYrFpAHipu9/cvo3czW8S8dtfsP95snlHsgPSxW+4quGw/40n5KFcN1KL58d7uK9U S+1u9lQaHdZWTLAUUamh2empDflIHps8PkvlypmF0+h5+vy72CakWbBO2G+vJ8c94t cp6YuQ+uScLdspK6EiezV5axIwUlezQCLdKCA/pK7M6z7VPzc6ydciGD/zmAUquKQH bb+07wsNrxldLjZtIDXdOLbF6bBIvy2iob9u2g5Kt/53C0aHKoRt2K3ESG5g0F5TEk F411xsHAu2vojzHNR0HCTLi5Igp/+0OO7y5B8GNENGE+tK4tNSRZAaUA2i1HA8V77z H4J8U4Xlap79w== Received: from mail-pj1-x102a.google.com (mail-pj1-x102a.google.com [IPv6:2607:f8b0:4864:20::102a]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 970E965674 for ; Thu, 12 May 2022 12:33:18 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="hYFRJJ3/"; dkim-atps=neutral Received: by mail-pj1-x102a.google.com with SMTP id qe3-20020a17090b4f8300b001dc24e4da73so5555935pjb.1 for ; Thu, 12 May 2022 03:33:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mbLUbwi5z4zvZkxI7LouTIRYkgWbjYMYSYQH9WUdIn4=; b=hYFRJJ3/Q727Kk9OpN/Uze9nVO95Ff37kL5AlpHHvFfvf6RK3AbMBaPTFlth1IHPCO E8O3MbEybYC3ZG2e/hD8jkIhYor99qdBgCO29lQ1n9Dg4wogWV2zP6Yr6w5saI3mljly u3OFfCAkaC03uM3OK8ubP6nFhb5b+PrAeKD/c= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mbLUbwi5z4zvZkxI7LouTIRYkgWbjYMYSYQH9WUdIn4=; b=qLRxxx6ZI3hoUAIjKcOE5JZ+UK6fXbUrEgve9KGuz9lB4mQocAifpUF2fhJDYcaByD uHp3k4+prLf5juZCdCTNp8786hTjhv8Awbqg7WYtxe9kVknLG5TUvxMsSCbClAY8Lhi9 PXNySmqxLlpZvBUHgTz2Pwjp2QqPIeczCDZokGtYGZmSrM5mZCc7FKe9RdMQPBYRVOtF cvbz0s6j7c7Z16+idmFOVRpnshH+4EEbHX+ca5SOYTWpywq6wUfZwOu+e6pe1PsqFRh1 KNM3iZyVp+2qVQ5ZzpTJiEmIssGzuo5ScxfilkKt/VwmbwJLCTdyg3kYx+vbICz4OAfQ y4VQ== X-Gm-Message-State: AOAM531SjTy/ZF/ti9ddcwIVdSWjNKOjZ/pPGxhnH1wgge0W9+5Rp7XE u9gYZ8n+xbSv/7U1AEVJMw1xQvoV6yKZRgNx X-Google-Smtp-Source: ABdhPJylwq7ABQ7PmENZf1mdfi5+FH2YdYwvAnexuILP/NUg836VQwJRDbqiB67YjsYiO1vQ303EDA== X-Received: by 2002:a17:90a:a410:b0:1dc:d03b:5623 with SMTP id y16-20020a17090aa41000b001dcd03b5623mr10288806pjp.95.1652351596647; Thu, 12 May 2022 03:33:16 -0700 (PDT) Received: from chenghaoyang-low.c.googlers.com.com (174.71.80.34.bc.googleusercontent.com. [34.80.71.174]) by smtp.gmail.com with ESMTPSA id t19-20020a62d153000000b005087c23ad8dsm3402219pfl.0.2022.05.12.03.33.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 12 May 2022 03:33:16 -0700 (PDT) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 12 May 2022 10:32:58 +0000 Message-Id: <20220512103258.324339-9-chenghaoyang@google.com> X-Mailer: git-send-email 2.36.0.512.ge40c2bad7a-goog In-Reply-To: <20220512103258.324339-1-chenghaoyang@google.com> References: <20220512103258.324339-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 8/8] Request StillCapture stream as default in Android adapter 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: , X-Patchwork-Original-From: Harvey Yang via libcamera-devel From: Cheng-Hao Yang Reply-To: Harvey Yang Cc: Harvey Yang , Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" If the pipeline handler accepts, the Android adapter requests to handle the StillCapture stream separately, instead of being mapped to an existing video/preview stream. Signed-off-by: Harvey Yang --- src/android/camera_device.cpp | 214 ++++++++++++++++++---------------- src/android/camera_device.h | 21 ++++ 2 files changed, 132 insertions(+), 103 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 00d48471..b8403cc2 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -36,23 +36,6 @@ LOG_DECLARE_CATEGORY(HAL) namespace { -/* - * \struct Camera3StreamConfig - * \brief Data to store StreamConfiguration associated with camera3_stream(s) - * \var streams List of the pairs of a stream requested by Android HAL client - * and CameraStream::Type associated with the stream - * \var config StreamConfiguration for streams - */ -struct Camera3StreamConfig { - struct Camera3Stream { - camera3_stream_t *stream; - CameraStream::Type type; - }; - - std::vector streams; - StreamConfiguration config; -}; - /* * Reorder the configurations so that libcamera::Camera can accept them as much * as possible. The sort rule is as follows. @@ -536,16 +519,6 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list) return -EINVAL; #endif - /* - * Generate an empty configuration, and construct a StreamConfiguration - * for each camera3_stream to add to it. - */ - std::unique_ptr config = camera_->generateConfiguration(); - if (!config) { - LOG(HAL, Error) << "Failed to generate camera configuration"; - return -EINVAL; - } - /* * Clear and remove any existing configuration from previous calls, and * ensure the required entries are available without further @@ -614,93 +587,79 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list) stream->usage |= GRALLOC_USAGE_HW_CAMERA_WRITE; } + std::unique_ptr config; + /* Now handle the MJPEG streams, adding a new stream if required. */ if (jpegStream) { - CameraStream::Type type; - int index = -1; - - /* Search for a compatible stream in the non-JPEG ones. */ - for (size_t i = 0; i < streamConfigs.size(); ++i) { - Camera3StreamConfig &streamConfig = streamConfigs[i]; - const auto &cfg = streamConfig.config; - - /* - * \todo The PixelFormat must also be compatible with - * the encoder. - */ - if (cfg.size.width != jpegStream->width || - cfg.size.height != jpegStream->height) - continue; - - LOG(HAL, Info) - << "Android JPEG stream mapped to libcamera stream " << i; - - type = CameraStream::Type::Mapped; - index = i; - - /* - * The source stream will be read by software to - * produce the JPEG stream. - */ - camera3_stream_t *stream = streamConfig.streams[0].stream; - stream->usage |= GRALLOC_USAGE_SW_READ_OFTEN; - break; - } + /* Check if the JPEG stream can be produced by software. */ + jpegStream->usage |= GRALLOC_USAGE_SW_WRITE_OFTEN; /* - * Without a compatible match for JPEG encoding we must - * introduce a new stream to satisfy the request requirements. + * \todo The pixelFormat should be a 'best-fit' choice + * and may require a validation cycle. This is not yet + * handled, and should be considered as part of any + * stream configuration reworks. */ - if (index < 0) { - /* - * \todo The pixelFormat should be a 'best-fit' choice - * and may require a validation cycle. This is not yet - * handled, and should be considered as part of any - * stream configuration reworks. - */ - Camera3StreamConfig streamConfig; - streamConfig.config.size.width = jpegStream->width; - streamConfig.config.size.height = jpegStream->height; - streamConfig.config.pixelFormat = formats::NV12; - streamConfigs.push_back(std::move(streamConfig)); - - LOG(HAL, Info) << "Adding " << streamConfig.config.toString() - << " for MJPEG support"; - - type = CameraStream::Type::Internal; - index = streamConfigs.size() - 1; - } - - /* The JPEG stream will be produced by software. */ - jpegStream->usage |= GRALLOC_USAGE_SW_WRITE_OFTEN; - - streamConfigs[index].streams.push_back({ jpegStream, type }); - } + Camera3StreamConfig sConfig; + sConfig.config.streamRole = libcamera::StreamRole::StillCapture; + sConfig.config.size.width = jpegStream->width; + sConfig.config.size.height = jpegStream->height; + sConfig.config.pixelFormat = formats::NV12; + + std::vector streamConfigsCopy(streamConfigs); + streamConfigsCopy.push_back(std::move(sConfig)); + + LOG(HAL, Info) << "Adding " << sConfig.config.toString() + << " for MJPEG support"; + + streamConfigsCopy.back().streams.push_back({ jpegStream, CameraStream::Type::Internal }); + + config = tryValidation(streamConfigsCopy, jpegStream); + if (config) { + streamConfigs = streamConfigsCopy; + } else { + bool foundCompatibleStream = false; + /* Search for a compatible stream in the non-JPEG ones. */ + for (size_t i = 0; i < streamConfigs.size(); ++i) { + Camera3StreamConfig &streamConfig = streamConfigs[i]; + const auto &cfg = streamConfig.config; + + /* + * \todo The PixelFormat must also be compatible with + * the encoder. + */ + if (cfg.size.width != jpegStream->width || + cfg.size.height != jpegStream->height) + continue; + + LOG(HAL, Info) + << "Android JPEG stream mapped to libcamera stream " << i; + foundCompatibleStream = true; + + /* + * The source stream will be read by software to + * produce the JPEG stream. + */ + camera3_stream_t *stream = streamConfig.streams[0].stream; + stream->usage |= GRALLOC_USAGE_SW_READ_OFTEN; + streamConfigs[i].streams.push_back({ jpegStream, CameraStream::Type::Mapped }); + break; + } - sortCamera3StreamConfigs(streamConfigs, jpegStream); - for (const auto &streamConfig : streamConfigs) { - config->addConfiguration(streamConfig.config); + if (!foundCompatibleStream) { + LOG(HAL, Error) + << "No compatibleStream found for jpeg"; - for (auto &stream : streamConfig.streams) { - streams_.emplace_back(this, config.get(), stream.type, - stream.stream, config->size() - 1); - stream.stream->priv = static_cast(&streams_.back()); + return -EINVAL; + } } } - switch (config->validate()) { - case CameraConfiguration::Valid: - break; - case CameraConfiguration::Adjusted: - LOG(HAL, Info) << "Camera configuration adjusted"; - - for (const StreamConfiguration &cfg : *config) - LOG(HAL, Info) << " - " << cfg.toString(); + if (!config) { + config = tryValidation(streamConfigs, jpegStream); + if (!config) + return -EINVAL; - return -EINVAL; - case CameraConfiguration::Invalid: - LOG(HAL, Info) << "Camera configuration invalid"; - return -EINVAL; } /* @@ -1527,3 +1486,52 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons return resultMetadata; } + +std::unique_ptr CameraDevice::tryValidation( + std::vector &streamConfigs, + const camera3_stream_t *jpegStream) +{ + /* + * Generate an empty configuration, and construct a StreamConfiguration + * for each camera3_stream to add to it. + */ + std::unique_ptr config = camera_->generateConfiguration(); + if (!config) { + LOG(HAL, Error) << "Failed to generate camera configuration"; + return nullptr; + } + + sortCamera3StreamConfigs(streamConfigs, jpegStream); + for (const auto &streamConfig : streamConfigs) { + config->addConfiguration(streamConfig.config); + + for (auto &stream : streamConfig.streams) { + streams_.emplace_back(this, config.get(), stream.type, + stream.stream, config->size() - 1); + stream.stream->priv = static_cast(&streams_.back()); + } + } + + switch (config->validate()) { + case CameraConfiguration::Valid: + break; + case CameraConfiguration::Adjusted: + LOG(HAL, Info) << "Camera configuration adjusted"; + + for (const StreamConfiguration &cfg : *config) + LOG(HAL, Info) << " - " << cfg.toString(); + + config.reset(); + break; + case CameraConfiguration::Invalid: + LOG(HAL, Info) << "Camera configuration invalid"; + + config.reset(); + break; + } + + if (!config) + streams_.clear(); + + return config; +} diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 64050416..8540e3f5 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -34,6 +34,23 @@ class Camera3RequestDescriptor; struct CameraConfigData; +/* + * \struct Camera3StreamConfig + * \brief Data to store StreamConfiguration associated with camera3_stream(s) + * \var streams List of the pairs of a stream requested by Android HAL client + * and CameraStream::Type associated with the stream + * \var config StreamConfiguration for streams + */ +struct Camera3StreamConfig { + struct Camera3Stream { + camera3_stream_t *stream; + CameraStream::Type type; + }; + + std::vector streams; + libcamera::StreamConfiguration config; +}; + class CameraDevice : protected libcamera::Loggable { public: @@ -101,6 +118,10 @@ private: std::unique_ptr getResultMetadata( const Camera3RequestDescriptor &descriptor) const; + std::unique_ptr tryValidation( + std::vector &streamConfigs, + const camera3_stream_t *jpegStream); + unsigned int id_; camera3_device_t camera3Device_;