From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 561F54FA7F for ; Tue, 24 Jun 2025 22:08:21 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id 3A3EA68D1C1; Wed, 25 Jun 2025 01:08:16 +0300 (EEST) Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id A7D8D687D90 for ; Wed, 25 Jun 2025 01:08:09 +0300 (EEST) Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-450dd065828so8525295e9.2 for ; Tue, 24 Jun 2025 15:08:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750802889; x=1751407689; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=kLLr9K9pvZcbI5oOtXpmSRSmu/hy/KdYO1QeE9c1Zqc=; b=XAAh1uVbYJ/LN00I1+Y5tnnAsJsUo2lHgmBA4nyO69zYKVECRs2Zacl1ZGKeK3JIM2 dYcHeZJSbPvqNtNh1NIi3V7yrwZ/jacgNUwMR35d6DWt8YqUj25O2AXA3pyhsAJLfKKy GJYVk4ZUTAbM8BgaC/mbCWA+KaHqYgnPoerVenw88dJCs6ErzECbke4iezfwb8loTiUV ICY/kJeN07+plzYkrCRJzMyvxPGrZ5Fbbj47M3TOrzU7qHhQGwdPQTpXgJtxvRTMN0Od l1bFep1FlJdz7dPqEMgB1JVBtbUD87cqFZpyPUAkIuNkR/YeaghphTMHwVB/0BnZVase kxeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750802889; x=1751407689; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=kLLr9K9pvZcbI5oOtXpmSRSmu/hy/KdYO1QeE9c1Zqc=; b=a6HTex+DhBQW0y0on1qAxH5SuE9PNBH3z2NZo9EL6FKxwsMLnAveVaCvWcTrvMuhX9 UZd5JmbP8ABYmWjVzbQYoCy8TwJqju/LS55aOYBWT/VM8N4zaxGMXFByWXiiAl3OIyuB 4eaUY45MeF8GpvwbTMieyQ7PJH2r6eZAqfvaUTeV5oSlR+K4jZ3kXhMmCpEuJn5U5O7E UTIbEf/9VtRN9Xt0xTyCgbhku9JsIrdTgHamTKaZTHGCNRJxsc7iGQDlaJKej7kpXo5W gHSKiE1fJRf3FlA8A3K5xNDg35RYbnf4kopX3DU0OMJbzKM4QsHp/D4S8DbQJIWwdMam FDZw== X-Gm-Message-State: AOJu0Yz0t5/3brdGzROS7M8NDH9ouBL9J/sNnxnm4UE74Z5lX61hN38q +ILU4Rfa9T7mLqfy+u3yugJlTO/1o2lHQi+GcTmGJTR96zrTEbS7oZvIWna/zQ== X-Gm-Gg: ASbGncuNrKMWeT9a9qDRF+e820x448n4A9rtCFOY0MgPoBkP0It0IuMSpZdYHGl20KI HQl9OKcAz7IsXL79eCEtb/LKARUpGxXSwVYUIQ1j6wjRE3ySC6bBGC3jVxo6QDPmRj8q3AVPkcg 8w6zG5ZpaVKyi/T3egyH6JAxG6V0DPy8w7gA4tyeOE4Q8F+ZX2hRmjiTvxVA/2NuwI5TFdTXur0 +K8BqMYz62erB4NsUVQPlcne2WuWc/Gwg1LWKOaZBffMK8bXgdk8slZCWMvSp+mAUD5CLaNxdqP 7VMVKUMiCkZm2YUQ1Y7E28JaTocR6xFSrYr4G+bnF5x/8z7pSCJT5JtJsxq/dEgCqmdpCfLekIb H8bl/fhoxL4eGMcL0sGotp/5zzbHLu7JclGQPObeGqENBMN6zqmkq/OHZARCt6hUCyRcZ5AWWa5 IuE3g6 X-Google-Smtp-Source: AGHT+IEPggP/R8wFulabNRpeClukP4bw2UzL4GO4iQYT9qLojK92OQVinm2uPhZZMRJdMOnQfH7YHw== X-Received: by 2002:a05:600c:4e0c:b0:43d:9d5:474d with SMTP id 5b1f17b1804b1-45381a7651fmr5608325e9.0.1750802888657; Tue, 24 Jun 2025 15:08:08 -0700 (PDT) Received: from ArmedBeast.fritz.box (p2003010237004500c9a67543cc7ba10e.dip0.t-ipconnect.de. [2003:102:3700:4500:c9a6:7543:cc7b:a10e]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4538233a8c6sm1456625e9.2.2025.06.24.15.08.07 for (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Tue, 24 Jun 2025 15:08:07 -0700 (PDT) From: Marvin Scholz To: ffmpeg-devel@ffmpeg.org Date: Wed, 25 Jun 2025 00:08:04 +0200 Message-Id: <20250624220805.50371-1-epirat07@gmail.com> X-Mailer: git-send-email 2.39.5 (Apple Git-154) MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/2] avformat/tee: refactor option processing X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: Instead of the convoluted nested macros, use a convenience helper function. While this makes the code slightly longer, it is now much clearer what is happening without running the file through a preprocessor first. Additionally do not mess with the internals of the dictionary, just to save two string copies. --- libavformat/tee.c | 98 +++++++++++++++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 32 deletions(-) diff --git a/libavformat/tee.c b/libavformat/tee.c index 0150ee9f22..0a6e9d0c82 100644 --- a/libavformat/tee.c +++ b/libavformat/tee.c @@ -80,8 +80,9 @@ static const AVClass tee_muxer_class = { .version = LIBAVUTIL_VERSION_INT, }; -static inline int parse_slave_failure_policy_option(const char *opt, TeeSlave *tee_slave) +static inline int parse_slave_failure_policy_option(const char *opt, void *ctx) { + TeeSlave *tee_slave = ctx; if (!opt) { tee_slave->on_fail = DEFAULT_SLAVE_FAILURE_POLICY; return 0; @@ -97,8 +98,9 @@ static inline int parse_slave_failure_policy_option(const char *opt, TeeSlave *t return AVERROR(EINVAL); } -static int parse_slave_fifo_policy(const char *use_fifo, TeeSlave *tee_slave) +static int parse_slave_fifo_policy(const char *use_fifo, void *ctx) { + TeeSlave *tee_slave = ctx; /*TODO - change this to use proper function for parsing boolean * options when there is one */ if (av_match_name(use_fifo, "true,y,yes,enable,enabled,on,1")) { @@ -111,8 +113,9 @@ static int parse_slave_fifo_policy(const char *use_fifo, TeeSlave *tee_slave) return 0; } -static int parse_slave_fifo_options(const char *fifo_options, TeeSlave *tee_slave) +static int parse_slave_fifo_options(const char *fifo_options, void *ctx) { + TeeSlave *tee_slave = ctx; return av_dict_parse_string(&tee_slave->fifo_options, fifo_options, "=", ":", 0); } @@ -152,6 +155,46 @@ static void close_slaves(AVFormatContext *avf) av_freep(&tee->slaves); } +typedef int (*OptionParserFunc)(const char *value, void *context); + +/** + * Retrieve and optionally copy or process the given dict key's value + * + * The dictionary value for \p key is retrieved, if it exists the + * value is passed to the \p handler function together with the + * \c context, if any. If the handler returns an error, it is returned + * to the caller. + * + * If \c out_value is not NULL, the value is also copied and assigned + * to that. + * + * After processing, the key is removed from the dictionary. + */ +static int dict_consume_value(AVDictionary **dict, const char *key, char **out_value, + OptionParserFunc handler, void *context) +{ + const AVDictionaryEntry *entry = av_dict_get(*dict, key, NULL, 0); + if (!entry) + return 0; + + if (handler) { + int ret = handler(entry->value, context); + if (ret < 0) + return ret; + } + + if (out_value) { + char *value_copy = av_strdup(entry->value); + if (!value_copy) + return AVERROR(ENOMEM); + + *out_value = value_copy; + } + + av_dict_set(dict, key, NULL, 0); + return 0; +} + static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave) { int ret; @@ -167,35 +210,26 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave) if ((ret = ff_tee_parse_slave_options(avf, slave, &options, &filename)) < 0) return ret; -#define CONSUME_OPTION(option, field, action) do { \ - AVDictionaryEntry *en = av_dict_get(options, option, NULL, 0); \ - if (en) { \ - field = en->value; \ - { action } \ - av_dict_set(&options, option, NULL, 0); \ - } \ - } while (0) -#define STEAL_OPTION(option, field) \ - CONSUME_OPTION(option, field, \ - en->value = NULL; /* prevent it from being freed */) -#define PROCESS_OPTION(option, function, on_error) do { \ - const char *value; \ - CONSUME_OPTION(option, value, if ((ret = function) < 0) \ - { { on_error } goto end; }); \ - } while (0) - - STEAL_OPTION("f", format); - STEAL_OPTION("select", select); - PROCESS_OPTION("onfail", - parse_slave_failure_policy_option(value, tee_slave), - av_log(avf, AV_LOG_ERROR, "Invalid onfail option value, " - "valid options are 'abort' and 'ignore'\n");); - PROCESS_OPTION("use_fifo", - parse_slave_fifo_policy(value, tee_slave), - av_log(avf, AV_LOG_ERROR, "Error parsing fifo options: %s\n", - av_err2str(ret));); - PROCESS_OPTION("fifo_options", - parse_slave_fifo_options(value, tee_slave), ;); + if ((ret = dict_consume_value(&options, "f", &format, NULL, NULL)) < 0) + goto end; + if ((ret = dict_consume_value(&options, "select", &select, NULL, NULL)) < 0) + goto end; + if ((ret = dict_consume_value(&options, "onfail", NULL, + parse_slave_failure_policy_option, tee_slave)) < 0) { + av_log(avf, AV_LOG_ERROR, "Invalid onfail option value, " + "valid options are 'abort' and 'ignore'\n"); + goto end; + } + if ((ret = dict_consume_value(&options, "use_fifo", NULL, + parse_slave_fifo_policy, tee_slave)) < 0) { + av_log(avf, AV_LOG_ERROR, "Error parsing fifo options: %s\n", + av_err2str(ret)); + goto end; + } + if ((ret = dict_consume_value(&options, "fifo_options", NULL, + parse_slave_fifo_options, tee_slave)) < 0) + goto end; + entry = NULL; while ((entry = av_dict_get(options, "bsfs", entry, AV_DICT_IGNORE_SUFFIX))) { /* trim out strlen("bsfs") characters from key */ -- 2.39.5 (Apple Git-154) _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".