From patchwork Thu Nov 29 02:02:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rostislav Pehlivanov X-Patchwork-Id: 11215 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 B193C44D9FA for ; Thu, 29 Nov 2018 04:11:37 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 549766898D8; Thu, 29 Nov 2018 04:11:38 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 99A0B689730 for ; Thu, 29 Nov 2018 04:11:32 +0200 (EET) Received: by mail-wm1-f51.google.com with SMTP id n133so578941wmd.4 for ; Wed, 28 Nov 2018 18:11:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=hu7zTW1SLVX0e+LkAk5ZYa/Pa3komSmRTgDsYWnAvjQ=; b=i9zM1fxSRodGC+ypgMlOPOE8q9UWich11wdZMwdxpymhTE143X6rFQR4PSwp+VJPa5 k+BNCEWbxxfp+7J9+eSqeNabNe6AzTJhuiADKCXB/BnfBdyQsLApkkCjazpxmqNtBDIV HY6PlxypkMhlLG+KkE+KskF2XDZcGuJ0FQVVy5XMOMOHGgpQvBmiB8Z1HHhzGDEWhIMQ 95nusIi73lmItdxc3DyuoIjsR1tVLA+IYs195hSMWhvHOdiQxMznGiWC/ghe3Mc+tf8J zoEbDwIDluogPaOqBMIju+80tWKCF4NAJtRoIhV8DJ2Aeefg5X57tzlUdMoEKSX1EpaC 2YLw== 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:mime-version :content-transfer-encoding; bh=hu7zTW1SLVX0e+LkAk5ZYa/Pa3komSmRTgDsYWnAvjQ=; b=cPupyq5u3CshJE7Ukkezps+lspLFmEOGR+R5nWmRQW5CUicyvfphnIPZgP6LYgkK+k HMyeMqIkqp1PYKqSdsspV/F4x7FsgDXVcAj7/gRHDIZAKv7AXQuROhRYqP0dqbG0ZXQY fShc86UhB2bKfu70kO4mbXsD7Hroi0Uz5Z1slDJJWCD5L3awHUki8k96R8Y4JFOcp2hh QPxuDG864SsTlP7bPs//4gwOTk4yznh8E4uZBmXLGvVPBbzQarunhdjNuninKPBsy6By BB1IX+GW2zQjHOHkOYV3ipTW38wxJqB3XcFoX1+S/wzcPS9Rgk7/43ZZT4O707E0F9mI G+VA== X-Gm-Message-State: AA+aEWanvhXuMQJzCwGa/7PadUzqa7zOzjpGIa/RNRa/k4d7eoKr2AlN qRbNqGzlmGOzsVqBEpTDLpe1e0iq X-Google-Smtp-Source: AFSGD/UNO2Cq5XYwedoCsyDrie9XAAVZMS7YgZGyH5OzYx8UEpt/PPdqY78jYVbxF/wL5u0NDnSEHw== X-Received: by 2002:a1c:a9d6:: with SMTP id s205mr4451632wme.131.1543456971009; Wed, 28 Nov 2018 18:02:51 -0800 (PST) Received: from moonbase.pars.ee ([2a00:23c4:7c91:2d00:9851:80c7:b53:22e5]) by smtp.gmail.com with ESMTPSA id a62sm447156wmf.47.2018.11.28.18.02.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 28 Nov 2018 18:02:50 -0800 (PST) From: Rostislav Pehlivanov To: ffmpeg-devel@ffmpeg.org Date: Thu, 29 Nov 2018 02:02:43 +0000 Message-Id: <20181129020243.20905-1-atomnuker@gmail.com> X-Mailer: git-send-email 2.19.2 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] [RFC] channel_layout: add support for ambisonics 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: Rostislav Pehlivanov Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" This is an RFC to add support for tagging channel layouts as ambisonics in a backward-compatible way. For now ambisonics up to third order are supported. The functions have been updated to support and propagate the AV_CH_LAYOUT_AMBISONICS flag. This is messy but does not require a new API for layouts. Perhaps the new proposed API might be a better solution, comments are welcome. --- doc/APIchanges | 4 ++ libavutil/channel_layout.c | 85 +++++++++++++++++++++----------------- libavutil/channel_layout.h | 19 ++++++++- libavutil/version.h | 4 +- 4 files changed, 72 insertions(+), 40 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index db1879e6e2..88e2d0764b 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2017-10-21 API changes, most recent first: +2018-xx-xx - xxxxxxxxxx - lavu 56.25.100 - channel_layout.h + Add AV_CH_LAYOUT_AMBISONICS, AV_CH_LAYOUT_AMBISONICS_1ST, + AV_CH_LAYOUT_AMBISONICS_2ND and AV_CH_LAYOUT_AMBISONICS_3RD. + -------- 8< --------- FFmpeg 4.1 was cut here -------- 8< --------- 2018-10-27 - 718044dc19 - lavu 56.21.100 - pixdesc.h diff --git a/libavutil/channel_layout.c b/libavutil/channel_layout.c index 3bd5ee29b7..30297138fe 100644 --- a/libavutil/channel_layout.c +++ b/libavutil/channel_layout.c @@ -33,42 +33,45 @@ struct channel_name { const char *name; + const char *ambisonics_name; const char *description; + const char *ambisonics_description; }; static const struct channel_name channel_names[] = { - [0] = { "FL", "front left" }, - [1] = { "FR", "front right" }, - [2] = { "FC", "front center" }, - [3] = { "LFE", "low frequency" }, - [4] = { "BL", "back left" }, - [5] = { "BR", "back right" }, - [6] = { "FLC", "front left-of-center" }, - [7] = { "FRC", "front right-of-center" }, - [8] = { "BC", "back center" }, - [9] = { "SL", "side left" }, - [10] = { "SR", "side right" }, - [11] = { "TC", "top center" }, - [12] = { "TFL", "top front left" }, - [13] = { "TFC", "top front center" }, - [14] = { "TFR", "top front right" }, - [15] = { "TBL", "top back left" }, - [16] = { "TBC", "top back center" }, - [17] = { "TBR", "top back right" }, - [29] = { "DL", "downmix left" }, - [30] = { "DR", "downmix right" }, - [31] = { "WL", "wide left" }, - [32] = { "WR", "wide right" }, - [33] = { "SDL", "surround direct left" }, - [34] = { "SDR", "surround direct right" }, - [35] = { "LFE2", "low frequency 2" }, + [0] = { "FL", "1", "front left", "ambisonics component 1" }, + [1] = { "FR", "2", "front right", "ambisonics component 2" }, + [2] = { "FC", "0", "front center", "ambisonics component 0" }, + [3] = { "LFE", "3", "low frequency", "ambisonics component 3" }, + [4] = { "BL", "4", "back left", "ambisonics component 4" }, + [5] = { "BR", "5", "back right", "ambisonics component 5" }, + [6] = { "FLC", "6", "front left-of-center", "ambisonics component 6" }, + [7] = { "FRC", "7", "front right-of-center", "ambisonics component 7" }, + [8] = { "BC", "8", "back center", "ambisonics component 8" }, + [9] = { "SL", "9", "side left", "ambisonics component 9" }, + [10] = { "SR", "10", "side right", "ambisonics component 10" }, + [11] = { "TC", "11", "top center", "ambisonics component 11" }, + [12] = { "TFL", "12", "top front left", "ambisonics component 12" }, + [13] = { "TFC", "13", "top front center", "ambisonics component 13" }, + [14] = { "TFR", "14", "top front right", "ambisonics component 14" }, + [15] = { "TBL", "15", "top back left", "ambisonics component 15" }, + [16] = { "TBC", NULL, "top back center", NULL }, + [17] = { "TBR", NULL, "top back right", NULL }, + [29] = { "DL", NULL, "downmix left", NULL }, + [30] = { "DR", NULL, "downmix right", NULL }, + [31] = { "WL", NULL, "wide left", NULL }, + [32] = { "WR", NULL, "wide right", NULL }, + [33] = { "SDL", NULL, "surround direct left", NULL }, + [34] = { "SDR", NULL, "surround direct right", NULL }, + [35] = { "LFE2", NULL, "low frequency 2", NULL }, }; -static const char *get_channel_name(int channel_id) +static const char *get_channel_name(int channel_id, int ambisonics) { if (channel_id < 0 || channel_id >= FF_ARRAY_ELEMS(channel_names)) return NULL; - return channel_names[channel_id].name; + return ambisonics ? channel_names[channel_id].ambisonics_name : + channel_names[channel_id].name; } static const struct { @@ -104,6 +107,10 @@ static const struct { { "octagonal", 8, AV_CH_LAYOUT_OCTAGONAL }, { "hexadecagonal", 16, AV_CH_LAYOUT_HEXADECAGONAL }, { "downmix", 2, AV_CH_LAYOUT_STEREO_DOWNMIX, }, + { "ambisonics_0th", 1, AV_CH_LAYOUT_AMBISONICS | AV_CH_LAYOUT_MONO }, + { "ambisonics_1st", 4, AV_CH_LAYOUT_AMBISONICS | (1 << 4) - 1 }, + { "ambisonics_2nd", 9, AV_CH_LAYOUT_AMBISONICS | (1 << 9) - 1 }, + { "ambisonics_3rd", 16, AV_CH_LAYOUT_AMBISONICS | (1 << 16) - 1 }, }; static uint64_t get_channel_layout_single(const char *name, int name_len) @@ -194,8 +201,8 @@ void av_bprint_channel_layout(struct AVBPrint *bp, int i, ch; av_bprintf(bp, " ("); for (i = 0, ch = 0; i < 64; i++) { - if ((channel_layout & (UINT64_C(1) << i))) { - const char *name = get_channel_name(i); + if (((channel_layout & ~AV_CH_LAYOUT_AMBISONICS) & (UINT64_C(1) << i))) { + const char *name = get_channel_name(i, channel_layout & AV_CH_LAYOUT_AMBISONICS); if (name) { if (ch > 0) av_bprintf(bp, "+"); @@ -219,7 +226,7 @@ void av_get_channel_layout_string(char *buf, int buf_size, int av_get_channel_layout_nb_channels(uint64_t channel_layout) { - return av_popcount64(channel_layout); + return av_popcount64(channel_layout & ~AV_CH_LAYOUT_AMBISONICS); } int64_t av_get_default_channel_layout(int nb_channels) { @@ -233,7 +240,7 @@ int64_t av_get_default_channel_layout(int nb_channels) { int av_get_channel_layout_channel_index(uint64_t channel_layout, uint64_t channel) { - if (!(channel_layout & channel) || + if (!((channel_layout & ~AV_CH_LAYOUT_AMBISONICS) & channel) || av_get_channel_layout_nb_channels(channel) != 1) return AVERROR(EINVAL); channel_layout &= channel - 1; @@ -246,8 +253,8 @@ const char *av_get_channel_name(uint64_t channel) if (av_get_channel_layout_nb_channels(channel) != 1) return NULL; for (i = 0; i < 64; i++) - if ((1ULL<