From patchwork Wed Apr 20 13:41:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hanlin Chen X-Patchwork-Id: 15687 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 7D7F3C3256 for ; Wed, 20 Apr 2022 13:41:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3217A65647; Wed, 20 Apr 2022 15:41:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1650462088; bh=J6txzjWeCAiHMi7PmlrLW+sYUOs5geXSWcPIXms8Bs4=; 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=eWyZDtnzNUIDBdUij99hbRb2m1Ctnp86ACIYQdZJ30AScrp0ZT5hqxuMo8ymCbt+q TbbSv/kBLa/Gf0X7LOedA98tido2d4kf8NUjhCdMqGkjFj2Ygwi4G3STkOhVZQZtRl jaQm1V372WcpmlmWteq4WDK3aVnQQHgMIloTBreHQThLB9uye/PuG6KRZKgopYs+Hg x9pUinlPrYrk/gmSSEkOUflZor8s6HrMJDDkYixP1G0kn2+1pih/A03CRaQRK7Z9+S BW1aEi4lTXGYuIC6SpFs8//S1DJl8C0P8q/dSmuIS7hdQmlbGpniiBMrwt5C3ZxU1j 6zv0lR93Z8qBQ== Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1C88D65647 for ; Wed, 20 Apr 2022 15:41:26 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="VN2cmy1s"; dkim-atps=neutral Received: by mail-pj1-x102e.google.com with SMTP id mp16-20020a17090b191000b001cb5efbcab6so4975377pjb.4 for ; Wed, 20 Apr 2022 06:41:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=wQ7kabCFShC5JW0bIzE4d2rAhrU+VGXBkHHFDjrsPk4=; b=VN2cmy1seOVH060o+tZkYyPKhr+KymiF462ud2w1P4KJlFXk+z40FiAeNAQOdai4qW VwUk1P8N4GdwW49VZQlh8iHCDp+xfnhpgPZ9Ah4s9As4HuBKL4/XfASSrB779ISj6Qc5 qkkpNYxgohDBA5W2tc69AgLFiWw794y0UUdtE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wQ7kabCFShC5JW0bIzE4d2rAhrU+VGXBkHHFDjrsPk4=; b=ZNGB1MwNqRRDgCORqGCe30vcEL8wCdDDeARqqEgPdeLvZuTCMSV+PVRarLOFXorSde aYiHXGUnju2bly/ZdDSNYDgBobcWXvsepneXCovbtr3NqcLAvrfAqHVF1fX/zm1NVr+i hbM5hO9bOjendXmpGRgnX3ysnjgOe6wKCkt4hO1WRMm3kaw5HWiV9AdAmrD0869gq6ce z+TWcBxOLo5rVCX5V7vS3a4jbcVeu1xDYQMDylS4qT/1Mn4UuR9GLf88ctI64WzWicN2 srCA5bjcuaF4RPn4XbNLtxiO40UM/dG/JEHJw/EwsSwxiMAt2yCQT2lLsM9ujQ5cgHtL hX5g== X-Gm-Message-State: AOAM531fpvRiq15Zud5RP/eGdK1TmRQQOIUjaGKivcobvoNtvxhij7Uu AjrluThJluPyq+zFE7536lA97hkQ8I8tjg== X-Google-Smtp-Source: ABdhPJyK5JoqxkaDyeRGkCQhg0jcElWjt18brHFPhFM0vyHyuc65aY4aMvOnyAifNa//7gFo1nSIWw== X-Received: by 2002:a17:902:728f:b0:156:24d3:ae1a with SMTP id d15-20020a170902728f00b0015624d3ae1amr20754225pll.9.1650462084072; Wed, 20 Apr 2022 06:41:24 -0700 (PDT) Received: from localhost ([2401:fa00:1:17:e17d:5346:b70d:ea81]) by smtp.gmail.com with UTF8SMTPSA id i15-20020a17090a058f00b001cd50a6ec5csm19445004pji.16.2022.04.20.06.41.23 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 20 Apr 2022 06:41:23 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 20 Apr 2022 21:41:19 +0800 Message-Id: <20220420134119.3306759-2-hanlinchen@chromium.org> X-Mailer: git-send-email 2.36.0.rc0.470.gd361397f0d-goog In-Reply-To: <20220420134119.3306759-1-hanlinchen@chromium.org> References: <20220420134119.3306759-1-hanlinchen@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 2/2] android: camera_hal_config: Use YamlParser to parse android HAL config 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: Han-Lin Chen via libcamera-devel From: Hanlin Chen Reply-To: Han-Lin Chen Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Use YamlParser to parse android HAL config files, instead of handling YAML tokens directly, as a preparation for the further parameter extension. Signed-off-by: Han-Lin Chen --- src/android/camera_hal_config.cpp | 334 +++++++----------------------- src/android/meson.build | 1 - 2 files changed, 74 insertions(+), 261 deletions(-) diff --git a/src/android/camera_hal_config.cpp b/src/android/camera_hal_config.cpp index aa90dac7..d269ab25 100644 --- a/src/android/camera_hal_config.cpp +++ b/src/android/camera_hal_config.cpp @@ -14,15 +14,15 @@ namespace filesystem = std::experimental::filesystem; #else #include #endif -#include #include #include -#include #include #include +#include + using namespace libcamera; LOG_DEFINE_CATEGORY(HALConfig) @@ -37,16 +37,10 @@ public: int parseConfigFile(FILE *fh, std::map *cameras); private: - std::string parseValue(); - std::string parseKey(); - int parseValueBlock(); - int parseCameraLocation(CameraConfigData *cameraConfigData, - const std::string &location); - int parseCameraConfigData(const std::string &cameraId); - int parseCameras(); - int parseEntry(); - - yaml_parser_t parser_; + int parseCameraConfigData(const std::string &cameraId, const YamlObject &); + int parseLocation(const YamlObject &, CameraConfigData &cameraConfigData); + int parseRotation(const YamlObject &, CameraConfigData &cameraConfigData); + std::map *cameras_; }; @@ -54,290 +48,110 @@ CameraHalConfig::Private::Private() { } -std::string CameraHalConfig::Private::parseValue() +int CameraHalConfig::Private::parseConfigFile(FILE *fh, + std::map *cameras) { - yaml_token_t token; - - /* Make sure the token type is a value and get its content. */ - yaml_parser_scan(&parser_, &token); - if (token.type != YAML_VALUE_TOKEN) { - yaml_token_delete(&token); - return ""; - } - yaml_token_delete(&token); - - yaml_parser_scan(&parser_, &token); - if (token.type != YAML_SCALAR_TOKEN) { - yaml_token_delete(&token); - return ""; - } - - std::string value(reinterpret_cast(token.data.scalar.value), - token.data.scalar.length); - yaml_token_delete(&token); - - return value; -} + /* + * Parse the HAL properties. + * + * Each camera properties block is a list of properties associated + * with the ID (as assembled by CameraSensor::generateId()) of the + * camera they refer to. + * + * cameras: + * "camera0 id": + * location: value + * rotation: value + * ... + * + * "camera1 id": + * location: value + * rotation: value + * ... + */ -std::string CameraHalConfig::Private::parseKey() -{ - yaml_token_t token; + cameras_ = cameras; - /* Make sure the token type is a key and get its value. */ - yaml_parser_scan(&parser_, &token); - if (token.type != YAML_SCALAR_TOKEN) { - yaml_token_delete(&token); - return ""; - } + std::unique_ptr root = YamlParser::parse(fh); + if (!root) + return -EINVAL; - std::string value(reinterpret_cast(token.data.scalar.value), - token.data.scalar.length); - yaml_token_delete(&token); + if (!root->isDictionary()) + return -EINVAL; - return value; -} + /* Parse property "cameras" */ + if (!root->contains("cameras")) + return -EINVAL; -int CameraHalConfig::Private::parseValueBlock() -{ - yaml_token_t token; + const YamlObject &yamlObjectCameras = (*root)["cameras"]; - /* Make sure the next token are VALUE and BLOCK_MAPPING_START. */ - yaml_parser_scan(&parser_, &token); - if (token.type != YAML_VALUE_TOKEN) { - yaml_token_delete(&token); + if (!yamlObjectCameras.isDictionary()) return -EINVAL; - } - yaml_token_delete(&token); - yaml_parser_scan(&parser_, &token); - if (token.type != YAML_BLOCK_MAPPING_START_TOKEN) { - yaml_token_delete(&token); - return -EINVAL; + std::vector cameraIds = yamlObjectCameras.getMemberNames(); + for (const std::string &cameraId : cameraIds) { + if (parseCameraConfigData(cameraId, + yamlObjectCameras[cameraId])) + return -EINVAL; } - yaml_token_delete(&token); return 0; } -int CameraHalConfig::Private::parseCameraLocation(CameraConfigData *cameraConfigData, - const std::string &location) -{ - if (location == "front") - cameraConfigData->facing = CAMERA_FACING_FRONT; - else if (location == "back") - cameraConfigData->facing = CAMERA_FACING_BACK; - else - return -EINVAL; +int CameraHalConfig::Private::parseCameraConfigData(const std::string &cameraId, + const YamlObject &cameraObject) - return 0; -} - -int CameraHalConfig::Private::parseCameraConfigData(const std::string &cameraId) { - int ret = parseValueBlock(); - if (ret) - return ret; - - /* - * Parse the camera properties and store them in a cameraConfigData - * instance. - * - * Add a safety counter to make sure we don't loop indefinitely in case - * the configuration file is malformed. - */ - CameraConfigData cameraConfigData; - unsigned int sentinel = 100; - bool blockEnd = false; - yaml_token_t token; - - do { - yaml_parser_scan(&parser_, &token); - switch (token.type) { - case YAML_KEY_TOKEN: { - yaml_token_delete(&token); - - /* - * Parse the camera property key and make sure it is - * valid. - */ - std::string key = parseKey(); - std::string value = parseValue(); - if (key.empty() || value.empty()) - return -EINVAL; - - if (key == "location") { - ret = parseCameraLocation(&cameraConfigData, value); - if (ret) { - LOG(HALConfig, Error) - << "Unknown location: " << value; - return -EINVAL; - } - } else if (key == "rotation") { - ret = std::stoi(value); - if (ret < 0 || ret >= 360) { - LOG(HALConfig, Error) - << "Unknown rotation: " << value; - return -EINVAL; - } - cameraConfigData.rotation = ret; - } else { - LOG(HALConfig, Error) - << "Unknown key: " << key; - return -EINVAL; - } - break; - } - - case YAML_BLOCK_END_TOKEN: - blockEnd = true; - [[fallthrough]]; - default: - yaml_token_delete(&token); - break; - } - - --sentinel; - } while (!blockEnd && sentinel); - if (!sentinel) + if (!cameraObject.isDictionary()) return -EINVAL; - (*cameras_)[cameraId] = cameraConfigData; - - return 0; -} + CameraConfigData &cameraConfigData = (*cameras_)[cameraId]; -int CameraHalConfig::Private::parseCameras() -{ - int ret = parseValueBlock(); - if (ret) { - LOG(HALConfig, Error) << "Configuration file is not valid"; - return ret; - } + /* Parse property "location" */ + if (parseLocation(cameraObject, cameraConfigData)) + return -EINVAL; - /* - * Parse the camera properties. - * - * Each camera properties block is a list of properties associated - * with the ID (as assembled by CameraSensor::generateId()) of the - * camera they refer to. - * - * cameras: - * "camera0 id": - * key: value - * key: value - * ... - * - * "camera1 id": - * key: value - * key: value - * ... - */ - bool blockEnd = false; - yaml_token_t token; - do { - yaml_parser_scan(&parser_, &token); - switch (token.type) { - case YAML_KEY_TOKEN: { - yaml_token_delete(&token); - - /* Parse the camera ID as key of the property list. */ - std::string cameraId = parseKey(); - if (cameraId.empty()) - return -EINVAL; - - ret = parseCameraConfigData(cameraId); - if (ret) - return -EINVAL; - break; - } - case YAML_BLOCK_END_TOKEN: - blockEnd = true; - [[fallthrough]]; - default: - yaml_token_delete(&token); - break; - } - } while (!blockEnd); + /* Parse property "rotation" */ + if (parseRotation(cameraObject, cameraConfigData)) + return -EINVAL; return 0; } -int CameraHalConfig::Private::parseEntry() +int CameraHalConfig::Private::parseLocation(const YamlObject &cameraObject, + CameraConfigData &cameraConfigData) { - int ret = -EINVAL; + if (!cameraObject.contains("location")) + return -EINVAL; - /* - * Parse each key we find in the file. - * - * The 'cameras' keys maps to a list of (lists) of camera properties. - */ + std::string location = cameraObject["location"].get(""); - std::string key = parseKey(); - if (key.empty()) - return ret; - - if (key == "cameras") - ret = parseCameras(); + if (location == "front") + cameraConfigData.facing = CAMERA_FACING_FRONT; + else if (location == "back") + cameraConfigData.facing = CAMERA_FACING_BACK; else - LOG(HALConfig, Error) << "Unknown key: " << key; + return -EINVAL; - return ret; + return 0; } -int CameraHalConfig::Private::parseConfigFile(FILE *fh, - std::map *cameras) +int CameraHalConfig::Private::parseRotation(const YamlObject &cameraObject, + CameraConfigData &cameraConfigData) { - cameras_ = cameras; - - int ret = yaml_parser_initialize(&parser_); - if (!ret) { - LOG(HALConfig, Error) << "Failed to initialize yaml parser"; - return -EINVAL; - } - yaml_parser_set_input_file(&parser_, fh); - - yaml_token_t token; - yaml_parser_scan(&parser_, &token); - if (token.type != YAML_STREAM_START_TOKEN) { - LOG(HALConfig, Error) << "Configuration file is not valid"; - yaml_token_delete(&token); - yaml_parser_delete(&parser_); + if (!cameraObject.contains("rotation")) return -EINVAL; - } - yaml_token_delete(&token); - yaml_parser_scan(&parser_, &token); - if (token.type != YAML_BLOCK_MAPPING_START_TOKEN) { - LOG(HALConfig, Error) << "Configuration file is not valid"; - yaml_token_delete(&token); - yaml_parser_delete(&parser_); + int32_t rotation = cameraObject["rotation"].get(-1); + + if (rotation < 0 || rotation >= 360) { + LOG(HALConfig, Error) + << "Unknown rotation: " << rotation; return -EINVAL; } - yaml_token_delete(&token); - - /* Parse the file and parse each single key one by one. */ - do { - yaml_parser_scan(&parser_, &token); - switch (token.type) { - case YAML_KEY_TOKEN: - yaml_token_delete(&token); - ret = parseEntry(); - break; - - case YAML_STREAM_END_TOKEN: - ret = -ENOENT; - [[fallthrough]]; - default: - yaml_token_delete(&token); - break; - } - } while (ret >= 0); - yaml_parser_delete(&parser_); - - if (ret && ret != -ENOENT) - LOG(HALConfig, Error) << "Configuration file is not valid"; - - return ret == -ENOENT ? 0 : ret; + + cameraConfigData.rotation = rotation; + return 0; } CameraHalConfig::CameraHalConfig() diff --git a/src/android/meson.build b/src/android/meson.build index 75b4bf20..1bba54de 100644 --- a/src/android/meson.build +++ b/src/android/meson.build @@ -3,7 +3,6 @@ android_deps = [ dependency('libexif', required : get_option('android')), dependency('libjpeg', required : get_option('android')), - dependency('yaml-0.1', required : get_option('android')), libcamera_private, ]