Show a patch.

GET /api/1.1/patches/15902/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 15902,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/15902/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/15902/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api",
        "name": "libcamera",
        "link_name": "libcamera",
        "list_id": "libcamera_core",
        "list_email": "libcamera-devel@lists.libcamera.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20220512103258.324339-7-chenghaoyang@google.com>",
    "date": "2022-05-12T10:32:56",
    "name": "[libcamera-devel,6/8] Configure imgu1 when necessary",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "78ba8990f12299f1a3707a64fddc49d90cc2b37c",
    "submitter": {
        "id": 117,
        "url": "https://patchwork.libcamera.org/api/1.1/people/117/?format=api",
        "name": "Cheng-Hao Yang",
        "email": "chenghaoyang@chromium.org"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/15902/mbox/",
    "series": [
        {
            "id": 3111,
            "url": "https://patchwork.libcamera.org/api/1.1/series/3111/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3111",
            "date": "2022-05-12T10:32:50",
            "name": "Use two imgus in ipu3 pipeline handler",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/3111/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/15902/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/15902/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>",
        "X-Original-To": "parsemail@patchwork.libcamera.org",
        "Delivered-To": "parsemail@patchwork.libcamera.org",
        "Received": [
            "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id D0ACFC326C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 12 May 2022 10:33:16 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 71E2665670;\n\tThu, 12 May 2022 12:33:16 +0200 (CEST)",
            "from mail-pl1-x634.google.com (mail-pl1-x634.google.com\n\t[IPv6:2607:f8b0:4864:20::634])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id DB87165657\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 12 May 2022 12:33:14 +0200 (CEST)",
            "by mail-pl1-x634.google.com with SMTP id x18so4467279plg.6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 12 May 2022 03:33:14 -0700 (PDT)",
            "from chenghaoyang-low.c.googlers.com.com\n\t(174.71.80.34.bc.googleusercontent.com. [34.80.71.174])\n\tby smtp.gmail.com with ESMTPSA id\n\tt19-20020a62d153000000b005087c23ad8dsm3402219pfl.0.2022.05.12.03.33.11\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tThu, 12 May 2022 03:33:12 -0700 (PDT)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1652351596;\n\tbh=VP2nw55uW/QB4dezhVhvnuEfHpreQgLzYfYwy7PCD+Y=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=xNICuhVe85cswJo9sdyHYBoEAgOkZut7WvSVtF9/4WM/h9RYsfkuJbrsLkBx5yQJ0\n\txj6sTPfqxH8o1+Ko40d4k+ghItca1YRng3JdITKZAgpi/Wse2tRLNF4GjLFuC+1hQR\n\tx5tAcrIkIqtj8oHFGSFTOVDcjeLNUmTMthGhVf8oR//sniRB00sv3iDl7HMTLp2KOB\n\tAQhVrg9cHdrpfG35A4I39/ihiHxr6r2c7kvRL6alIo9ONWo93W7hVRbsqvyUIvewD0\n\tWJNSVl1HP45OKObnDNElh4+FJTcI0CzLbSfPaQPemntbv/GwlKMujoJved7jn+LI8o\n\tRveZgCQcsRAbQ==",
            "v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org;\n\ts=google; \n\th=from:to:cc:subject:date:message-id:in-reply-to:references\n\t:mime-version:content-transfer-encoding;\n\tbh=DUzZlYpdbMeE74ukQP/CyVaVtD+Vet5FhfkFoC2n4bw=;\n\tb=T6OhWMWHzJy59BplgHZvi8xJb7uaLRO/FrrHmPm4keEtmaYu1p7v/oUofse811Y4MJ\n\tZCY2aNra2dC6Ss//tXiXu87eX4nOqJKPcw2c04QdaCSzacZp4rTLSDwrryY8Nea/v3yT\n\tTuryYsDw4XBuQ6rpFs5Fukka76pKfsGVrN5xc="
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=chromium.org\n\theader.i=@chromium.org header.b=\"T6OhWMWH\"; \n\tdkim-atps=neutral",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references:mime-version:content-transfer-encoding;\n\tbh=DUzZlYpdbMeE74ukQP/CyVaVtD+Vet5FhfkFoC2n4bw=;\n\tb=VedINhCOthJ/dmsA+SU3UfbWYdnffRikJ9UH9jVD9xPrBm/EToMZOArqFjSPfEkQXW\n\t/xBbuzMZx1MTukc0f86lbPe15Gf+pAvxWytOKH0v2B5H2xk0zp7XgIsMO5zTT1ScVdAF\n\tK8aFojhWTT/tdcNVuBMoj2BpbKy+a+Kr4z9fYSavO713cgwKlvn/cCl93euu+AbKSxP3\n\tHeCkXVVu0UTO6+3NVQlEq2PFq28qMvCTcb3A8smVU2fw4BeXQp34u1FNkKMhv2wK/uqR\n\t6QKm7fh/yn83G+KU3W1iBYFrbzPxScZhluHdXE9afdPpWpX6ktVO25rB+0eqhgvlI2W3\n\tuHQA==",
        "X-Gm-Message-State": "AOAM531I4LDp4s/9L0ZXZ7Vnazd2pGKncaI9x72ka3ESZKUc7iaOvBfS\n\t6kj2j3bofCQT8axkSrjxkOzepvRJf6gbOQ6a",
        "X-Google-Smtp-Source": "ABdhPJzPgxkhewf5JekBqacrDARL9eroLDLOkmyFhMWJfaA/W3DWASosYOBBjK1rDm08kltZ6ScOsQ==",
        "X-Received": "by 2002:a17:90a:9483:b0:1dc:5fb2:9b89 with SMTP id\n\ts3-20020a17090a948300b001dc5fb29b89mr9998497pjo.235.1652351592975; \n\tThu, 12 May 2022 03:33:12 -0700 (PDT)",
        "X-Google-Original-From": "Harvey Yang <chenghaoyang@google.com>",
        "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",
        "Content-Transfer-Encoding": "8bit",
        "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": "<libcamera-devel.lists.libcamera.org>",
        "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>",
        "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>",
        "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>",
        "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>",
        "From": "Harvey Yang via libcamera-devel <libcamera-devel@lists.libcamera.org>",
        "Reply-To": "Harvey Yang <chenghaoyang@chromium.org>",
        "Cc": "Harvey Yang <chenghaoyang@google.com>,\n\tHarvey Yang <chenghaoyang@chromium.org>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "This patch configure and setup imgu1 when still capture and other\nstreams are enabled. If only still capture is enabled, imgu0 is still\nbeing used with IPU3PipeModeStillCapture.\n\nStill capture stream will be enabled in the following patches though.\n\nSigned-off-by: Harvey Yang <chenghaoyang@chromium.org>\n---\n src/libcamera/pipeline/ipu3/ipu3.cpp | 179 +++++++++++++++++++++++----\n 1 file changed, 155 insertions(+), 24 deletions(-)",
    "diff": "diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\nindex 8ce1968f..9498b1b0 100644\n--- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n@@ -55,9 +55,11 @@ public:\n \n \tint loadIPA();\n \n+\tvoid tryReturnBuffer(FrameBuffer *buffer);\n \tvoid imguOutputBufferReady(FrameBuffer *buffer);\n \tvoid cio2BufferReady(FrameBuffer *buffer);\n \tvoid paramBufferReady(FrameBuffer *buffer);\n+\tvoid captureParamBufferReady(FrameBuffer *buffer);\n \tvoid statBufferReady(FrameBuffer *buffer);\n \tvoid queuePendingRequests();\n \tvoid cancelPendingRequests();\n@@ -93,6 +95,8 @@ private:\n \tvoid paramsBufferReady(unsigned int id);\n \tvoid setSensorControls(unsigned int id, const ControlList &sensorControls,\n \t\t\t       const ControlList &lensControls);\n+\n+\tstd::map<FrameBuffer *, int> inputReturnCounters;\n };\n \n class IPU3CameraConfiguration : public CameraConfiguration\n@@ -106,11 +110,14 @@ public:\n \tStatus validate() override;\n \n \tconst StreamConfiguration &cio2Format() const { return cio2Configuration_; }\n-\tconst ImgUDevice::PipeConfig imguConfig() const { return pipeConfig_; }\n+\tconst ImgUDevice::PipeConfig imguConfig0() const { return pipeConfig0_; }\n+\tconst ImgUDevice::PipeConfig imguConfig1() const { return pipeConfig1_; }\n \n \t/* Cache the combinedTransform_ that will be applied to the sensor */\n \tTransform combinedTransform_;\n \n+\tbool onlyStillCapture_ = false;\n+\n private:\n \t/*\n \t * The IPU3CameraData instance is guaranteed to be valid as long as the\n@@ -120,7 +127,8 @@ private:\n \tconst IPU3CameraData *data_;\n \n \tStreamConfiguration cio2Configuration_;\n-\tImgUDevice::PipeConfig pipeConfig_;\n+\tImgUDevice::PipeConfig pipeConfig0_;\n+\tImgUDevice::PipeConfig pipeConfig1_;\n };\n \n class PipelineHandlerIPU3 : public PipelineHandler\n@@ -168,6 +176,9 @@ private:\n \tMediaDevice *cio2MediaDev_;\n \tMediaDevice *imguMediaDev_;\n \n+\tbool onlyStillCapture_ = false;\n+\tbool useImgu1_ = false;\n+\n \tCamera *inUseCamera_ = nullptr;\n \n \tstd::vector<IPABuffer> ipaBuffers_;\n@@ -408,8 +419,8 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()\n \n \t/* Only compute the ImgU configuration if a YUV stream has been requested. */\n \tif (yuvCount) {\n-\t\tpipeConfig_ = data_->imgu0_->calculatePipeConfig(&pipe);\n-\t\tif (pipeConfig_.isNull()) {\n+\t\tpipeConfig0_ = data_->imgu0_->calculatePipeConfig(&pipe);\n+\t\tif (pipeConfig0_.isNull()) {\n \t\t\tLOG(IPU3, Error) << \"Failed to calculate pipe configuration: \"\n \t\t\t\t\t << \"unsupported resolutions.\";\n \t\t\treturn Invalid;\n@@ -519,8 +530,14 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)\n \tIPU3CameraData *data = cameraData(camera);\n \tStream *outStream = &data->outStream_;\n \tStream *vfStream = &data->vfStream_;\n+\tStream *outCaptureStream = &data->outCaptureStream_;\n \tCIO2Device *cio2 = &data->cio2_;\n \tV4L2DeviceFormat outputFormat;\n+\n+\tonlyStillCapture_ = config->onlyStillCapture_;\n+\tImgUDevice::PipeConfig imguConfig1 = config->imguConfig1();\n+\tuseImgu1_ = !imguConfig1.isNull();\n+\n \tint ret;\n \n \t/*\n@@ -565,6 +582,12 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)\n \tif (ret)\n \t\treturn ret;\n \n+\tif (useImgu1_) {\n+\t\tret = imgu1_.enableLinks(true);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n \t/*\n \t * Pass the requested stream size to the CIO2 unit and get back the\n \t * adjusted format to be propagated to the ImgU output devices.\n@@ -607,14 +630,20 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)\n \t * stream has been requested: return here to skip the ImgU configuration\n \t * part.\n \t */\n-\tImgUDevice::PipeConfig imguConfig = config->imguConfig();\n-\tif (imguConfig.isNull())\n+\tImgUDevice::PipeConfig imguConfig0 = config->imguConfig0();\n+\tif (imguConfig0.isNull())\n \t\treturn 0;\n \n-\tret = imgu0_.configure(imguConfig, &cio2Format);\n+\tret = imgu0_.configure(imguConfig0, &cio2Format);\n \tif (ret)\n \t\treturn ret;\n \n+\tif (useImgu1_) {\n+\t\tret = imgu1_.configure(imguConfig1, &cio2Format);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n \t/* Apply the format to the configured streams output devices. */\n \tStreamConfiguration *mainCfg = nullptr;\n \tStreamConfiguration *vfCfg = nullptr;\n@@ -633,6 +662,15 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)\n \t\t\tret = imgu0_.configureViewfinder(cfg, &outputFormat);\n \t\t\tif (ret)\n \t\t\t\treturn ret;\n+\t\t} else if (stream == outCaptureStream) {\n+\t\t\tASSERT(useImgu1_);\n+\t\t\tret = imgu1_.configureOutput(cfg, &outputFormat);\n+\t\t\tif (ret)\n+\t\t\t\treturn ret;\n+\n+\t\t\tret = imgu1_.configureViewfinder(cfg, &outputFormat);\n+\t\t\tif (ret)\n+\t\t\t\treturn ret;\n \t\t}\n \t}\n \n@@ -648,22 +686,35 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)\n \t}\n \n \t/* Apply the \"pipe_mode\" control to the ImgU subdevice. */\n-\tControlList ctrls(imgu0_.imgu_->controls());\n+\tControlList ctrls0(imgu0_.imgu_->controls());\n \t/*\n \t * Set the ImgU pipe mode to 'Video' unconditionally to have statistics\n \t * generated.\n-\t *\n-\t * \\todo Figure out what the 'Still Capture' mode is meant for, and use\n-\t * it accordingly.\n \t */\n-\tctrls.set(V4L2_CID_IPU3_PIPE_MODE,\n-\t\t  static_cast<int32_t>(IPU3PipeModeVideo));\n-\tret = imgu0_.imgu_->setControls(&ctrls);\n+\tctrls0.set(V4L2_CID_IPU3_PIPE_MODE,\n+\t\t   static_cast<int32_t>(onlyStillCapture_ ?\n+\t\t\t   IPU3PipeModeStillCapture : IPU3PipeModeVideo));\n+\tret = imgu0_.imgu_->setControls(&ctrls0);\n \tif (ret) {\n \t\tLOG(IPU3, Error) << \"Unable to set pipe_mode control\";\n \t\treturn ret;\n \t}\n \n+\tif (useImgu1_) {\n+\t\tControlList ctrls1(imgu1_.imgu_->controls());\n+\t\t/*\n+\t\t * \\todo Figure out what the 'Still Capture' mode is meant for,\n+\t\t * and use it accordingly.\n+\t\t */\n+\t\tctrls1.set(V4L2_CID_IPU3_PIPE_MODE,\n+\t\t\t   static_cast<int32_t>(IPU3PipeModeStillCapture));\n+\t\tret = imgu1_.imgu_->setControls(&ctrls1);\n+\t\tif (ret) {\n+\t\t\tLOG(IPU3, Error) << \"Unable to set pipe_mode control\";\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n \tipa::ipu3::IPAConfigInfo configInfo;\n \tconfigInfo.sensorControls = data->cio2_.sensor()->controls();\n \n@@ -672,8 +723,8 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)\n \t\tconfigInfo.lensControls = lens->controls();\n \n \tconfigInfo.sensorInfo = sensorInfo;\n-\tconfigInfo.bdsOutputSize = config->imguConfig().bds;\n-\tconfigInfo.iif = config->imguConfig().iif;\n+\tconfigInfo.bdsOutputSize = config->imguConfig0().bds;\n+\tconfigInfo.iif = config->imguConfig0().iif;\n \n \tret = data->ipa_->configure(configInfo, &data->ipaControls_);\n \tif (ret) {\n@@ -789,8 +840,8 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] const ControlLis\n \tCIO2Device *cio2 = &data->cio2_;\n \tint ret;\n \n-\timgu0_.input_->bufferReady.connect(&data->cio2_,\n-\t\t\t\t\t   &CIO2Device::tryReturnBuffer);\n+\timgu0_.input_->bufferReady.connect(data,\n+\t\t\t\t\t   &IPU3CameraData::tryReturnBuffer);\n \timgu0_.output_->bufferReady.connect(data,\n \t\t\t\t\t    &IPU3CameraData::imguOutputBufferReady);\n \timgu0_.viewfinder_->bufferReady.connect(data,\n@@ -799,6 +850,16 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] const ControlLis\n \t\t\t\t\t   &IPU3CameraData::paramBufferReady);\n \timgu0_.stat_->bufferReady.connect(data,\n \t\t\t\t\t  &IPU3CameraData::statBufferReady);\n+\n+\tif (useImgu1_) {\n+\t\timgu1_.input_->bufferReady.connect(data,\n+\t\t\t\t&IPU3CameraData::tryReturnBuffer);\n+\t\timgu1_.output_->bufferReady.connect(data,\n+\t\t\t\t&IPU3CameraData::imguOutputBufferReady);\n+\t\timgu1_.param_->bufferReady.connect(data,\n+\t\t\t\t&IPU3CameraData::captureParamBufferReady);\n+\t}\n+\n \t/* Disable test pattern mode on the sensor, if any. */\n \tret = cio2->sensor()->setTestPatternMode(\n \t\tcontrols::draft::TestPatternModeEnum::TestPatternModeOff);\n@@ -830,10 +891,17 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] const ControlLis\n \tif (ret)\n \t\tgoto error;\n \n+\tif (useImgu1_) {\n+\t\tret = imgu1_.start();\n+\t\tif (ret)\n+\t\t\tgoto error;\n+\t}\n+\n \treturn 0;\n \n error:\n \timgu0_.stop();\n+\timgu1_.stop();\n \tcio2->stop();\n \tdata->ipa_->stop();\n \tfreeBuffers(camera);\n@@ -844,6 +912,12 @@ error:\n \timgu0_.viewfinder_->bufferReady.disconnect();\n \timgu0_.param_->bufferReady.disconnect();\n \timgu0_.stat_->bufferReady.disconnect();\n+\timgu1_.input_->bufferReady.disconnect();\n+\timgu1_.output_->bufferReady.disconnect();\n+\timgu1_.param_->bufferReady.disconnect();\n+\n+\tonlyStillCapture_ = false;\n+\tuseImgu1_ = false;\n \tinUseCamera_ = nullptr;\n \n \treturn ret;\n@@ -859,6 +933,7 @@ void PipelineHandlerIPU3::stopDevice(Camera *camera)\n \tdata->ipa_->stop();\n \n \tret |= imgu0_.stop();\n+\tret |= imgu1_.stop();\n \tret |= data->cio2_.stop();\n \tif (ret)\n \t\tLOG(IPU3, Warning) << \"Failed to stop camera \" << camera->id();\n@@ -870,7 +945,12 @@ void PipelineHandlerIPU3::stopDevice(Camera *camera)\n \tdata->imgu0_->viewfinder_->bufferReady.disconnect();\n \tdata->imgu0_->param_->bufferReady.disconnect();\n \tdata->imgu0_->stat_->bufferReady.disconnect();\n+\tdata->imgu1_->input_->bufferReady.disconnect();\n+\tdata->imgu1_->output_->bufferReady.disconnect();\n+\tdata->imgu1_->param_->bufferReady.disconnect();\n \n+\tonlyStillCapture_ = false;\n+\tuseImgu1_ = false;\n \tinUseCamera_ = nullptr;\n }\n \n@@ -1316,22 +1396,45 @@ void IPU3CameraData::paramsBufferReady(unsigned int id)\n \tif (!info)\n \t\treturn;\n \n+\tbool hasYuv = false;\n+\tbool hasCapture = false;\n \t/* Queue all buffers from the request aimed for the ImgU. */\n \tfor (auto it : info->request->buffers()) {\n \t\tconst Stream *stream = it.first;\n \t\tFrameBuffer *outbuffer = it.second;\n \n-\t\tif (stream == &outStream_)\n+\t\tif (stream == &outStream_) {\n+\t\t\thasYuv = true;\n \t\t\timgu0_->output_->queueBuffer(outbuffer);\n-\t\telse if (stream == &vfStream_)\n+\t\t} else if (stream == &vfStream_) {\n+\t\t\thasYuv = true;\n \t\t\timgu0_->viewfinder_->queueBuffer(outbuffer);\n+\t\t} else if (stream == &outCaptureStream_) {\n+\t\t\thasCapture = true;\n+\n+\t\t\timgu1_->output_->queueBuffer(outbuffer);\n+\t\t}\n \t}\n \n-\timgu0_->param_->queueBuffer(info->paramBuffer);\n-\timgu0_->stat_->queueBuffer(info->statBuffer);\n-\timgu0_->input_->queueBuffer(info->rawBuffer);\n+\tif (hasYuv) {\n+\t\tinputReturnCounters[info->rawBuffer] += 1;\n \n-\tinfo->captureParamDequeued = true;\n+\t\timgu0_->param_->queueBuffer(info->paramBuffer);\n+\t\timgu0_->stat_->queueBuffer(info->statBuffer);\n+\t\timgu0_->input_->queueBuffer(info->rawBuffer);\n+\t} else {\n+\t\tinfo->paramDequeued = true;\n+\t\tinfo->metadataProcessed = true;\n+\t}\n+\n+\tif (hasCapture) {\n+\t\tinputReturnCounters[info->rawBuffer] += 1;\n+\n+\t\timgu1_->param_->queueBuffer(info->captureParamBuffer);\n+\t\timgu1_->input_->queueBuffer(info->rawBuffer);\n+\t} else {\n+\t\tinfo->captureParamDequeued = true;\n+\t}\n }\n \n void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata)\n@@ -1352,6 +1455,14 @@ void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata)\n  * Buffer Ready slots\n  */\n \n+void IPU3CameraData::tryReturnBuffer(FrameBuffer *buffer)\n+{\n+\tif (--inputReturnCounters[buffer] == 0) {\n+\t\tinputReturnCounters.erase(buffer);\n+\t\tcio2_.tryReturnBuffer(buffer);\n+\t}\n+}\n+\n /**\n  * \\brief Handle buffers completion at the ImgU output\n  * \\param[in] buffer The completed buffer\n@@ -1443,6 +1554,26 @@ void IPU3CameraData::paramBufferReady(FrameBuffer *buffer)\n \t\tpipe()->completeRequest(request);\n }\n \n+void IPU3CameraData::captureParamBufferReady(FrameBuffer *buffer)\n+{\n+\tIPU3Frames::Info *info = frameInfos_.find(buffer);\n+\tif (!info)\n+\t\treturn;\n+\n+\tinfo->captureParamDequeued = true;\n+\n+\t/*\n+\t * tryComplete() will delete info if it completes the IPU3Frame.\n+\t * In that event, we must have obtained the Request before hand.\n+\t *\n+\t * \\todo Improve the FrameInfo API to avoid this type of issue\n+\t */\n+\tRequest *request = info->request;\n+\n+\tif (frameInfos_.tryComplete(info))\n+\t\tpipe()->completeRequest(request);\n+}\n+\n void IPU3CameraData::statBufferReady(FrameBuffer *buffer)\n {\n \tIPU3Frames::Info *info = frameInfos_.find(buffer);\n",
    "prefixes": [
        "libcamera-devel",
        "6/8"
    ]
}