From patchwork Tue Nov 29 13:45:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 17911 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 3D63FC3286 for ; Tue, 29 Nov 2022 13:45:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6736F6333F; Tue, 29 Nov 2022 14:45:44 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1669729544; bh=1EA1gvNx34pZxdnIB7ZSD4Wdr6IySmZ/YynJ3Jr6Q6U=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=enynkB3gZNsUiif6sHzz42DmU6ZyUfKS/fvydLw6TIsRN9ehURiOd/BWEL4WG7Uvd 7gAL3PIGWwJ+UDjMf7dlARHsV900oO8IqwkCNxGBDo4VIMpLx09x8itrvcAQGiCP7I WiuK181jbaMKssLbMvX+skDhCNQuPIv/VF+hEAy1luHNXpbxp4+1tpYzj3sTsKfSfS AnBb9cyUcnr9g2xbWOAsJAQ10RQ+bPjuX4Vns0MExHJQHXz0t5gX3y+OvXrNU57Vn9 W9GfYvWVeUXKYRiENFs2vhR7xzZGyhymWE7WMs6ijpDboRzGRhu/kXd5QyhwPuYRLK /N2rPK3KVTXUg== Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [IPv6:2a00:1450:4864:20::433]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 418F96333F for ; Tue, 29 Nov 2022 14:45:41 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="XIF19mHa"; dkim-atps=neutral Received: by mail-wr1-x433.google.com with SMTP id o5so13157447wrm.1 for ; Tue, 29 Nov 2022 05:45:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=dkxuoYbUAgoPHTxggyZSVJLmHd9EHdyyBvKcOavddOY=; b=XIF19mHaGq1E4KuSfYVKpvTX/ZzQBKRoB27mn6q6uEaI+TEBiJ7Esxf81fmBYAe3eu PtsWGQtlhYW/H659R0fa4XZj+wzIjMhWrTcjWU4zLVMRmh6koA/gEuM4bogxTSYzfeu0 q/LmGAOsI4mtDbckCq4+to01TRraqXTtdTHugveVyT3/5nkNoNKE0GOJjoHHpxIHKBXb gMyTwGgmvnMpKPk0FM0mQ8z+7usAhNKjlZJCTfL0duImHj64Zkxow7nhjSgcNSZ9lBRU Da+ySwMURnkOiBfQAa/xhcoNJ399iaI+Ni781yOGCM4fUQdrxLgSO7GOMC4l6AbSpmy5 7QjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dkxuoYbUAgoPHTxggyZSVJLmHd9EHdyyBvKcOavddOY=; b=3W1Y/deR3IPX5itefDqIogNF0lfgZjBTSKFnWcSbS+nSGYUcyAymybm/e2eJDI579i ohWiXrIbIUhycyzI0Uc8PO52ayIdiwttx3OfBX1guaQfy+CTNy5pDWSljMQYoT1+IS2r 6KEqfXIBuCJ7pkdQIMXRsy3pcJ5Ta7klBCQy26oPvA1T9s6wPPMUReDKqAufUHrQYlWU mwryLdpuh4dzSz+QuXkWed/lqd/BK/857Xuk1+okDZe0fur1meJszwHWp1BRYtMWrUJs gQsLQN6U4ly2b5ZeYEMBMtGhSdW+U6LCqKwfzMbgdn34D1QVYtDIGwzVSZfgrXWO/8ax /I9A== X-Gm-Message-State: ANoB5pnVuRlb6zGnhKk3JAuk74A6DvS7/d+5XbRr9UgONX6hvoBMyo0c pB/++2iiuBcrwJPfEtnkSDRQ2QEg/GvQyA== X-Google-Smtp-Source: AA0mqf46rZJoMI4+hsthmbEvHxcGpVhNE628tZlPO7OvKyByX0dI3AyChVgxduhloXsTx696OuLo0A== X-Received: by 2002:adf:eb88:0:b0:22e:3e3b:24fe with SMTP id t8-20020adfeb88000000b0022e3e3b24femr32906375wrn.668.1669729540598; Tue, 29 Nov 2022 05:45:40 -0800 (PST) Received: from naush-laptop.localdomain ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id n8-20020a05600c3b8800b003cfbbd54178sm3565636wms.2.2022.11.29.05.45.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Nov 2022 05:45:40 -0800 (PST) To: libcamera-devel@lists.libcamera.org Date: Tue, 29 Nov 2022 13:45:28 +0000 Message-Id: <20221129134534.2933-5-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221129134534.2933-1-naush@raspberrypi.com> References: <20221129134534.2933-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 04/10] pipeline: raspberrypi: Read config parameters from a file 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: Naushir Patuck via libcamera-devel From: Naushir Patuck Reply-To: Naushir Patuck Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Read the platform configuration parameters from default.json config file. Use the PipelineHandler::configurationFile() helper to determine the full path of the file. The default.json filename can be overridden by the user setting the LIBCAMERA_RPI_CONFIG_FILE environment variable giving the full path of the custom file. Add config parameter validation to ensure bad parameters cannot cause the pipeline handler to stop working. Currently three parameters are available through the json file: "min_unicam_buffers" The minimum number of internal Unicam buffers to allocate. "min_total_unicam_buffers" The minimum number of internal + external Unicam buffers that must be allocated. "num_output0_buffers" Number of internal ISP Output0 buffers to allocate. Signed-off-by: Naushir Patuck Reviewed-by: David Plowman --- .../pipeline/raspberrypi/data/default.json | 20 ++++++ .../pipeline/raspberrypi/data/meson.build | 8 +++ .../pipeline/raspberrypi/meson.build | 2 + .../pipeline/raspberrypi/raspberrypi.cpp | 61 +++++++++++++++++++ 4 files changed, 91 insertions(+) create mode 100644 src/libcamera/pipeline/raspberrypi/data/default.json create mode 100644 src/libcamera/pipeline/raspberrypi/data/meson.build diff --git a/src/libcamera/pipeline/raspberrypi/data/default.json b/src/libcamera/pipeline/raspberrypi/data/default.json new file mode 100644 index 000000000000..d709e31850af --- /dev/null +++ b/src/libcamera/pipeline/raspberrypi/data/default.json @@ -0,0 +1,20 @@ +{ + "version": 1.0, + "target": "bcm2835", + + "pipeline_handler": + { + # The minimum number of internal buffers to be allocated for Unicam. + # This value must be greater than 0, but less than or equal to min_total_unicam_buffers. + "min_unicam_buffers": 2, + + # The minimum total (internal + external) buffer count used for Unicam. + # The number of internal buffers allocated for Unicam is given by: + # internal buffer count = max(min_unicam_buffers, + # min_total_unicam_buffers - external buffer count) + "min_total_unicam_buffers": 4, + + # The number of internal buffers used for ISP Output0. This must be set to 1. + "num_output0_buffers": 1 + } +} diff --git a/src/libcamera/pipeline/raspberrypi/data/meson.build b/src/libcamera/pipeline/raspberrypi/data/meson.build new file mode 100644 index 000000000000..232f8b43c5fd --- /dev/null +++ b/src/libcamera/pipeline/raspberrypi/data/meson.build @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: CC0-1.0 + +conf_files = files([ + 'default.json', +]) + +install_data(conf_files, + install_dir : libcamera_datadir / 'pipeline/raspberrypi') diff --git a/src/libcamera/pipeline/raspberrypi/meson.build b/src/libcamera/pipeline/raspberrypi/meson.build index f1a2f5ee72c2..48235f887501 100644 --- a/src/libcamera/pipeline/raspberrypi/meson.build +++ b/src/libcamera/pipeline/raspberrypi/meson.build @@ -5,3 +5,5 @@ libcamera_sources += files([ 'raspberrypi.cpp', 'rpi_stream.cpp', ]) + +subdir('data') diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index f2b695af2399..ce411453db0a 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -40,6 +41,7 @@ #include "libcamera/internal/media_device.h" #include "libcamera/internal/pipeline_handler.h" #include "libcamera/internal/v4l2_videodevice.h" +#include "libcamera/internal/yaml_parser.h" #include "dma_heaps.h" #include "rpi_stream.h" @@ -313,6 +315,7 @@ public: }; Config config_; + unsigned int numUnicamBuffers; private: void checkRequestCompleted(); @@ -1154,6 +1157,19 @@ int PipelineHandlerRPi::queueRequestDevice(Camera *camera, Request *request) */ stream->setExternalBuffer(buffer); } + + if (!buffer) { + if (stream == &data->isp_[Isp::Output0] && !data->config_.numOutput0Buffers) { + LOG(RPI, Error) << "Output0 buffer must be provided in the request."; + return -EINVAL; + } + + if (stream == &data->unicam_[Unicam::Image] && !data->numUnicamBuffers) { + LOG(RPI, Error) << "Unicam Image buffer must be provided in the request."; + return -EINVAL; + } + } + /* * If no buffer is provided by the request for this stream, we * queue a nullptr to the stream to signify that it must use an @@ -1419,6 +1435,7 @@ int PipelineHandlerRPi::registerCamera(MediaDevice *unicam, MediaDevice *isp, Me int PipelineHandlerRPi::configurePipelineHandler(RPiCameraData *data) { RPiCameraData::Config &config = data->config_; + std::string filename; config = { .minUnicamBuffers = 2, @@ -1426,6 +1443,49 @@ int PipelineHandlerRPi::configurePipelineHandler(RPiCameraData *data) .numOutput0Buffers = 1, }; + char const *configFromEnv = utils::secure_getenv("LIBCAMERA_RPI_CONFIG_FILE"); + if (!configFromEnv || *configFromEnv == '\0') + filename = configurationFile("raspberrypi", "default.json"); + else + filename = std::string(configFromEnv); + + if (filename.empty()) + return -EINVAL; + + File file(filename); + if (!file.open(File::OpenModeFlag::ReadOnly)) { + LOG(RPI, Error) << "Failed to open configuration file '" << filename << "'"; + return -EIO; + } + + LOG(RPI, Info) << "Using configuration file '" << filename << "'"; + + std::unique_ptr root = YamlParser::parse(file); + if (!root) { + LOG(RPI, Error) << "Failed to parse configuration file, using defaults!"; + return -EINVAL; + } + + ASSERT((*root)["version"].get() == 1.0); + + const YamlObject &phConfig = (*root)["pipeline_handler"]; + config.minUnicamBuffers = + phConfig["min_unicam_buffers"].get(config.minUnicamBuffers); + config.minTotalUnicamBuffers = + phConfig["min_total_unicam_buffers"].get(config.minTotalUnicamBuffers); + config.numOutput0Buffers = + phConfig["num_output0_buffers"].get(config.numOutput0Buffers); + + if (config.minTotalUnicamBuffers < config.minUnicamBuffers) { + LOG(RPI, Error) << "Invalid configuration: min_total_unicam_buffers must be >= min_unicam_buffers!"; + return -EINVAL; + } + + if (config.minTotalUnicamBuffers < 1) { + LOG(RPI, Error) << "Invalid configuration: min_total_unicam_buffers must be >= 1!"; + return -EINVAL; + } + return 0; } @@ -1492,6 +1552,7 @@ int PipelineHandlerRPi::prepareBuffers(Camera *camera) */ numBuffers = std::max(data->config_.minUnicamBuffers, minBuffers - numRawBuffers); + data->numUnicamBuffers = numBuffers; } else if (stream == &data->isp_[Isp::Input]) { /* * ISP input buffers are imported from Unicam, so follow