From patchwork Tue Sep 8 21:18:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 22184 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id ED36844BD83 for ; Wed, 9 Sep 2020 00:19:33 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D80AD68B73F; Wed, 9 Sep 2020 00:19:33 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f65.google.com (mail-wm1-f65.google.com [209.85.128.65]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5F87C68B6D4 for ; Wed, 9 Sep 2020 00:19:30 +0300 (EEST) Received: by mail-wm1-f65.google.com with SMTP id w2so359414wmi.1 for ; Tue, 08 Sep 2020 14:19:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=FZFv6R5/ZEEnDNgFqdwvQEFkfS6IHzWnLNcksMJgZuQ=; b=GyJiYQvR6Oq9MxFLwZL8OSneMuX60sUtCaAdqpBhABDonYKNv7P53DkVW47Fkdx1yY yIGIaqGHBEpH42RONfHy8kOdbMhr30CviMxgEkc2ugS9UFVuolRfZ3A459AJoOwLXe90 cl/T403p6sRpOZz/8tV3Tmm8DfdAgiEXMuT1wtIfNQMfnx5UTpQc7hRhAWnmmW0UVehc 1q/+hDStjtolhiGSh+Q5F9NI6KofuBgVyxZqozWhe2OzYCqcwKP2ZoV4uuQF4p1u/B3C Z00Gn+fdygHhz3gqeMeoh1nEeZnE573fPCswaHA7w347lOesneL8FgE9yiCwI/n3BhLS My9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=FZFv6R5/ZEEnDNgFqdwvQEFkfS6IHzWnLNcksMJgZuQ=; b=BLyyAHw+oz67G8xbMxY1Bwh1/jter5UHrbPBmqRZ3IMV3um5RaAk8oi9KdusN+j6on gEMiJeYt7WyhHulq2t0Rcaoj6pPrqy7bRM/5dqk5az4cd/7eYzKAe0DwrF8ShxcithAi ONgXq+KQtj6nbchag+/Fe5JIu2YeUJtJJrj2hNTwLw7Y2T5qGpFgiE6DmGCCSc68WFV8 Z1z+PlpURHYPQ/HBtOH1Ndi35/Y8pIYCW061JYMHluVkOzJJRyOvoz7hG7uglD1k0lQb InTT7BzeLC/w07kz2rs9VWNcsa0msUbRJC4halOfhjn2i9tkPALkJHrnHcEumeCvR1La WHoQ== X-Gm-Message-State: AOAM533pDYQANZYv5nRdKXR7E3aNBIcDOo/DuHWy+yNnj5wFkwFGCZuJ FWDX5KWOskj+ZGDjIi41m/J/1vMQ9Dw= X-Google-Smtp-Source: ABdhPJzm14JXZP/IZJcqg3nQ2+Lu1qB/yvhZohtqZ4ggUM37WZ7MqYShOjas4/L8SkGW2G5VRvL2yg== X-Received: by 2002:a05:600c:228e:: with SMTP id 14mr343353wmf.17.1599599969574; Tue, 08 Sep 2020 14:19:29 -0700 (PDT) Received: from sblaptop.fritz.box (ipbcc1fb0f.dynamic.kabel-deutschland.de. [188.193.251.15]) by smtp.gmail.com with ESMTPSA id a15sm1074304wrn.3.2020.09.08.14.19.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Sep 2020 14:19:29 -0700 (PDT) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Tue, 8 Sep 2020 23:18:41 +0200 Message-Id: <20200908211856.16290-10-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200908211856.16290-1-andreas.rheinhardt@gmail.com> References: <20200908211856.16290-1-andreas.rheinhardt@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 10/25] avfilter/af_headphone: Simplify parsing channel mapping string X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 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 Cc: Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" When parsing the channel mapping string (a string containing '|' delimited tokens each of which is supposed to contain a channel name like "FR"), the old code would at each step read up to seven uppercase characters from the input string and give this to av_get_channel_layout() to parse. The returned layout is then checked for being a layout with a single channel set by computing its logarithm. Besides being overtly complicated this also has the drawback of relying on the assumption that every channel name consists of at most seven uppercase letters only; but said assumption is wrong: The abbreviation of the second low frequency channel is LFE2. Furthermore it treats garbage like "FRfoo" as valid channel. This commit changes this by using av_get_channel_layout() directly; furthermore, av_get_channel_layout_nb_channels() (which uses popcount) is used to find out the number of channels instead of the custom code to calculate the logarithm. (As a consequence, certain other formats to specify the channel layouts are now accepted (like the hex versions of av_get_channel_layout()); but this is actually not bad at all.) Signed-off-by: Andreas Rheinhardt --- libavfilter/af_headphone.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/libavfilter/af_headphone.c b/libavfilter/af_headphone.c index 8db712e9a0..32939af854 100644 --- a/libavfilter/af_headphone.c +++ b/libavfilter/af_headphone.c @@ -87,26 +87,14 @@ typedef struct HeadphoneContext { uint64_t mapping[64]; } HeadphoneContext; -static int parse_channel_name(char **arg, uint64_t *rchannel, char *buf) +static int parse_channel_name(const char *arg, uint64_t *rchannel) { - int len, i, channel_id = 0; - uint64_t layout, layout0; - - if (sscanf(*arg, "%7[A-Z]%n", buf, &len)) { - layout0 = layout = av_get_channel_layout(buf); - for (i = 32; i > 0; i >>= 1) { - if (layout >= 1LL << i) { - channel_id += i; - layout >>= i; - } - } - if (channel_id >= 64 || layout0 != 1ULL << channel_id) - return AVERROR(EINVAL); - *rchannel = layout0; - *arg += len; - return 0; - } - return AVERROR(EINVAL); + uint64_t layout = av_get_channel_layout(arg); + + if (av_get_channel_layout_nb_channels(layout) != 1) + return AVERROR(EINVAL); + *rchannel = layout; + return 0; } static void parse_map(AVFilterContext *ctx) @@ -124,15 +112,14 @@ static void parse_map(AVFilterContext *ctx) while ((arg = av_strtok(p, "|", &tokenizer))) { uint64_t out_channel; - char buf[8]; p = NULL; - if (parse_channel_name(&arg, &out_channel, buf)) { + if (parse_channel_name(arg, &out_channel)) { av_log(ctx, AV_LOG_WARNING, "Failed to parse \'%s\' as channel name.\n", arg); continue; } if (used_channels & out_channel) { - av_log(ctx, AV_LOG_WARNING, "Ignoring duplicate channel '%s'.\n", buf); + av_log(ctx, AV_LOG_WARNING, "Ignoring duplicate channel '%s'.\n", arg); continue; } used_channels |= out_channel;