From patchwork Mon Sep 19 13:25:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: erkki.seppala.ext@nokia.com X-Patchwork-Id: 639 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.140.134 with SMTP id o128csp1001094vsd; Mon, 19 Sep 2016 06:28:45 -0700 (PDT) X-Received: by 10.28.105.209 with SMTP id z78mr8806123wmh.31.1474291725248; Mon, 19 Sep 2016 06:28:45 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id b21si7532802wmd.77.2016.09.19.06.28.44; Mon, 19 Sep 2016 06:28:45 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@nokia.onmicrosoft.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE dis=NONE) header.from=nokia.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 43EDC68A075; Mon, 19 Sep 2016 16:26:08 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from EUR01-DB5-obe.outbound.protection.outlook.com (mail-db5eur01on0107.outbound.protection.outlook.com [104.47.2.107]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E9DBD689FD7 for ; Mon, 19 Sep 2016 16:26:01 +0300 (EEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nokia.onmicrosoft.com; s=selector1-nokia-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=8Co6GknbcwBGJAffBiJcBQWsg2fXeZJR07xqlNWztrE=; b=gxmN8/OxW2AdqxyCAnEgoTCpJwADXPYUeOJGMIctyYSFILhs9v0klIUHAYmF0irYQq+4UYWucTc/gCyucpMt4LP+yqUL73v4Y7w9TlvC3WnUjV6zNMrKxMjcoQlNMqVS2nKcwsx6O/8BJIq9M/8Sz6X3hDQGeLQfvtgcZzLbTf4= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=erkki.seppala.ext@nokia.com; Received: from erkkise-laptop.vincit.intranet (131.228.2.24) by VI1PR0701MB2544.eurprd07.prod.outlook.com (10.168.139.145) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.629.8; Mon, 19 Sep 2016 13:26:14 +0000 Received: by erkkise-laptop.vincit.intranet (Postfix, from userid 1000) id E99914F0F61; Mon, 19 Sep 2016 16:25:48 +0300 (EEST) From: =?UTF-8?q?Erkki=20Sepp=C3=A4l=C3=A4?= To: Date: Mon, 19 Sep 2016 16:25:42 +0300 Message-ID: <1474291548-17810-20-git-send-email-erkki.seppala.ext@nokia.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1474291548-17810-1-git-send-email-erkki.seppala.ext@nokia.com> References: <1471943019-14136-1-git-send-email-erkki.seppala.ext@nokia.com> <1474291548-17810-1-git-send-email-erkki.seppala.ext@nokia.com> MIME-Version: 1.0 X-Originating-IP: [131.228.2.24] X-ClientProxiedBy: BN6PR17CA0031.namprd17.prod.outlook.com (10.175.189.17) To VI1PR0701MB2544.eurprd07.prod.outlook.com (10.168.139.145) X-MS-Office365-Filtering-Correlation-Id: c84f8fea-35e8-4312-4a8a-08d3e0908811 X-Microsoft-Exchange-Diagnostics: 1; VI1PR0701MB2544; 2:CgLN+F3n7puHzBXmt+6rdq6kqFapPf2N+hALiy9+O1QX55syi2sgPJ0I1ewQpOGwXpTAy9eLlZRTZduKyyH78BstMniWeTSazwtKTbEwz8JYY3b4GSDJg1IvfMkhLS6EJl51QaTx4EfvsrV9Wphh/Nat1GoP43oSL97IlxY1ZW00R2GCLgbm/vz+GEj32X5x; 3:mzzP5oBko9EyBWh80G+Tom/4fgeCZrzBitOgqM2YfrswUljIeebbb5B7EhC0GNYsFFdb1dOg/kRxHnOog23AgpLqnSbwx1ctitFyqGa66TDyJAHJe0inLycHPZ80f2/Q X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:VI1PR0701MB2544; X-Microsoft-Exchange-Diagnostics: 1; VI1PR0701MB2544; 25:tVgDFbNC/nVXaQlW8pt6uUfLsVKbBf7Iw1EBiEJoMCxs66weYzQ4GiqQVaOHNNyEwz+DEXW/xz6HSB11KKGep96aEUYKJJHSoGpcimYQuMC97HSalgo2T83z6PogslqlXsplus8Adpt+sQ6HQtKeqGDb3OiOqLUP/rNrudbaFi+Puos93yZluF4fqGPExHPr+0UeOhPwoOBP/2UlIZHG28j7TZM31uF8BkBLyuuH4NEuPGHU8Gkva7G4fBYd6LhxBDpEzZWCO/OhgdLVLPQvJhTcrHQQLy4xNLDBEVY3i6PgaZlMV7FGToNJPKrY0SkIUwdRMIgxq5yK0xHz81VTB9P8fTIu3yVQhdQtBWsB61aixAQthhu4OgWc30qgt6JwBuNMbg8J70Mgu9MfLbGXoE8vCW0CCaYvnrSy3TH+PmEY8DCNpD7gnSaSeBWJgFTfQQLBkyxabx2HsRTt7bp441+rQOGhgf6OrQJBcJ/bIuZrCIS9vmnAtZmAVRQT5J50gm8KCSWM36JKNJ8rECz34AdPXsju1DBlXlA+ZQMvYlxJ3kGgQMvV8VNkxIk01F3e1Rpd4vWm4x+j1+lIfvqMze3T9e7mx0J+7syLqWOR185Z300tO0GrHtxDAQGrWJxH9L30cvcRSRL/DoM02Wlx/ROOVwU+fu/hVxKXAvuD8v/tgluepwNGZ5R/QTD+t5No; 31:VrnVZX3x7WnyOeYIKtqsZW4vp2T8bOyZenpToL6FC0Bf3MUcAx2vzQrc+xnhta5BvjJxEPTbgTiWfWXlbuhKs5eLRdRT696piUBLtb6Gmdwiu+qweeEhw8CPm2ZJrQJjSAI6uvjFDBWJf3ajqUKdfZKM5soCOYxPxRAjHT9n0IMtBIXaz71x5Ox/wzNDAYWwJKPt84zRCwfynRloHgIehP+R3mwB2N5/H2FpzELFrEE= X-Microsoft-Exchange-Diagnostics: 1; VI1PR0701MB2544; 20:KVdOlGZyNxEh2Jz64KswWa0JUnxy/5p6WCmlLx2PmVNGj0OwHNaNyBoB8obVXWIrhEBkihOI70mnj7YrZ6hZ4iIUOA28Br8OkxmkRs7PqSqh614vqexIuieFMwt2mqH2+R4StSY6S04KN9RSWAHSoJ2ptdPrbLFbYrepCZ1lBjZtvRtifUc3ltMB5XzbZ7+zqSiqHjYX3YrGa8nwgqsnLepbaIR8L5iZJE9SRiNEVU39FpUx8nUg8EX4ERo1nqlcJXn6tc9oJ4ZvN8KHvv3NPPyu3QEZ9gM/aadTeMJwSbqo6Jb2LKGX3/usyfWNJpVK16BjUW+JGOMcvd4PDuc8KbOAtsJ95R2e6xVhHf9PhNyfE0gheY3BRWUmtG+hRMFFWQ5ldc94tvIdaPrqUVEpfhG+QtUvgPOgPGeRPBOvWSwuCniIWQRvu2SzcWYgS/LjP9Z/0NJW6ZsaCH3/uUGSN744sHARqL0R2TLzrC0gsBeCxqPymRDEXKTBx3S++B8w X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(82608151540597); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040176)(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046)(6055026); SRVR:VI1PR0701MB2544; BCL:0; PCL:0; RULEID:; SRVR:VI1PR0701MB2544; X-Microsoft-Exchange-Diagnostics: 1; VI1PR0701MB2544; 4:1rSDdMRzR+yuGlbFy2UGj9DsrmDbJ+h2CUU48mvBz5/NX/YLkByDQLfIWQB5SMVK8hpFuCG0cMYW9+NNKr6Onycxu6MPMgVwCrlIhL4urN4gJsrletTlZHyRoQqjr/kZ9D8w0GF4VIr5DIumNR1tqDhV9yt6bDTWaE28RuAK9Ux3UlxkBMcMyef369l+LF410k3ivdwMqUj6nLL1H2h20Jx00MAS0hlPFt1BWjj81UKhXthKB83wZzH9MjJ2qAn0Kp1oTwlnVq7+b0qkFc2YD1BR8MYa3xAPI6ZKEuOlVWKG0VcqeLOvG9dkEQr/VxmzY2Lu2z6mwkFlf1wYqOZ+g+5PVp62oorVGcNkKs0PGYMgaYLc7dyKJqFYZlRDWKtBzNW1qLNIu/tYVr44KkpG1TsLDIddAYeb7ANSovUvFsHu08TqSzVIebAqW0jEhukObXYRXK54cW2BIe6LDPDTPg== X-Forefront-PRVS: 0070A8666B X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(4630300001)(6009001)(7916002)(199003)(189002)(4326007)(107886002)(5820100001)(2906002)(90966002)(68736007)(110136003)(450100001)(50226002)(4001430100002)(81166006)(81156014)(42186005)(8676002)(50466002)(7736002)(7846002)(52956003)(305945005)(45336002)(92566002)(46386002)(19580395003)(47776003)(3846002)(105586002)(586003)(2351001)(6116002)(66066001)(229853001)(189998001)(97736004)(122856001)(23676002)(5660300001)(33646002)(19580405001)(36756003)(2870700001)(106356001)(76176999)(50986999)(101416001)(2950100001)(86362001)(2004002)(309714004)(19627235001); DIR:OUT; SFP:1102; SCL:1; SRVR:VI1PR0701MB2544; H:erkkise-laptop.vincit.intranet; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: nokia.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtWSTFQUjA3MDFNQjI1NDQ7MjM6V3BHQTdGS004alI5aUo1WUFJajlTUFhM?= =?utf-8?B?VDRnelBjWStQWEpzMCtvWmRhOEtmOTBmNjNqd3VvWkRjbnVxU3dTZkFYUTRD?= =?utf-8?B?dWJrOXJuY1dVWjVJUzVvZkduTUgydDN3L29vSytuYUhTTndDdzd2bHpsRytI?= =?utf-8?B?WC9hN3BOQUxsUklYZWQyY2puOHRwRWQ2YnREZCtIR1hrNWtsTnorak56bGZG?= =?utf-8?B?OUNYMmdYTFJwb0h5WVVoUnJsQ1BCZTNZamUwL2tKaGVORFEwdmR0bWI2VHVM?= =?utf-8?B?dENrK1RLSmpwTjJibnZ6SG9UWEZuTHMya0RCamk5VTRCeE50bXVBbGYwZ3lB?= =?utf-8?B?djVKUGdHZmxVaTlYUTBUVTZDRnFxQVJjaEplTUR2Uk9TeFNXK2xodGt0ZC9v?= =?utf-8?B?STFBUGJRbENxL1I0Zkk0ZlBUSTJNeElvSTRhZmdqSnpuN0VocjkyTlM1VjZj?= =?utf-8?B?c1ByeHBTVGdNNldBSHYwd0IzQ1N1SUZLWjJpWlJ3Y1ByUE9zV0RnTVQxdXJL?= =?utf-8?B?VWRlbG9OOForNUxzWWYwL2U3S2t0cWM4aWo5bG5vVWpCOGRwR2JnMnhXR1ZD?= =?utf-8?B?TWNMRVFvRWViVURhc1QraTFKWk5oeFp3TzAzQnJHUm0wQnJlZjI5bTZzdVdK?= =?utf-8?B?cm1ENm5abzBhcEhRWjBvbHp4WWNVSHppZktnSTQxY3F5N0Jta2RXVFNQMExP?= =?utf-8?B?amZ1S1kwdlBqVU5hN3hNOUl2RGxlVjhTTHd4WStDNWpURmcyRi9wZWMrM21p?= =?utf-8?B?MUQzVTFXQzFYbDFSNDZOS3QrOFZXQzNtd1VUTXVMREtXNDNkRnlWcXBsTElG?= =?utf-8?B?L2djZkRNdHM5T1FCRWJBV0p0SEtzTnNRK3FuLy85aTB2elRQSjA5Q3lCMFlt?= =?utf-8?B?d3lQNGRmcGVGVVU1aC9RWW5HRGZGWDBmVzhnK1dJU2dUa2lBREVhQWp5MFRG?= =?utf-8?B?RGx1L3VRellRNVdzN0QwbVhYSFVyeThHZGhSNDl4cGtTN0lxQ2JJNzlPL042?= =?utf-8?B?STg5RzNTUGJsQnBZVnVSYVBDcGRjYnRleStvV3VHYnZkSEc1R3h5RzA3RTFr?= =?utf-8?B?RUFPeXFNTHJhOVhxa1Rzdm55N0NENkE1NUlwQWZGd0dUTWNoVHMycDNYaGRV?= =?utf-8?B?eE5MMk5vcnErYk1qVUFiNFdndkVzK0RMSEcxc2dUZnFyemwwUWh6VE1wNm9k?= =?utf-8?B?V3dLa1IvVjhoS3pkTTJVL2tnR1JDMXdZMW1veUc3WWw2bzNWWjRwb1JrN0lG?= =?utf-8?B?bkRQYTZmZk0xb0lVZEtjVGpGbGJSTXhtVU9mSVhGcEFJeEQwTU1YdnhXNEUy?= =?utf-8?B?QTh4cWNQZTZGZjdtVDl0RFoybmJFZCtmSzJDbjJ0QlQ1U0ZzRFd1Yk1hUlpL?= =?utf-8?B?S0oybWdBYktIYTcrQkl0RmlrRlB1cUpPTkZGOHQwVnptcXJYL2d6OWlZQjl4?= =?utf-8?B?aGRweHFSWms5Y2lvaThxa3lFcE5aZVNCM0JyU0tkaHBMbUJXU3FNVCswaDNR?= =?utf-8?B?cC9Ed0NYZVJKMU5SYkpBc25YS1I3eDl4ZExWUnZmOVV2U2NBN25ZTWhPdVhk?= =?utf-8?B?aWNTeTBna0g4NTVFVTIvOElqbTFEbEpyZmo0aFNpOG1iNHRlRXhqN2Rldy9X?= =?utf-8?B?RjhtbS92RGRCMmRReU9DakF5NkU5ZzRYeElIbUx4RVMrU1gzUzdmSTgrUVVT?= =?utf-8?B?RWlLd1RrdXQ0UGNLYXRSWUNEaEpQaVIrbG54WlhUYVhjcU9kUXZKTDdmV1RQ?= =?utf-8?B?UW9ZM3Nxeko1SUt1aWErUGhxSTkrakhPQlZwdWdDK2pGWGpGM1NUUTJkd1pV?= =?utf-8?B?blJ5WTdBdlRseDJISmp3QU5xMkV4SzdROXFETDQzd3MrazJ0QT09?= X-Microsoft-Exchange-Diagnostics: 1; VI1PR0701MB2544; 6:bGu1uLSAs07H9ffKpgbpZI7ftE0GllRA9MxJJuTLjNc+ig4vzWqc2ETFyTIMtXwIfkJtZ6TlXU/k0gDDMHTJCBYeER/lvB61BvaGEBjxUQcAA8y+RRSmhsnU3OyWOq8qcrYy1Y+fZLT+AeZBBO4kHMdeR7Pzi0vJ0N0rbaeI0dmpqlvNEoW9YEx8K8FVcOudJQBYrTogB/3GJtTIAYDArT9+YEwgMA5bw0bNQUt60QwaNAwc3N40zS6wfV7uVhPZU62ItupQkPSHDaYyHle7p4aRSCCL/O3+N0hb1RkeT3+dQvYJuusGv7K1kFZmJfOaDtSxcBk4UKjXJYDE6k3aYg==; 5:Mo8Z9ds3RJseARwGHdWBBCBKo9pblQaEegHpUoEOHJMZxyT9E6AKzo6GrG/pysRM+3CErK+loLsC2RdsM+bpTV/g3UHzHFfX8SPZ6p2jeYBfctAiP4W0yLQv6ZA2DYp/Ei9DIC2JEByChC5JxHBR5Q==; 24:2O7PtLGt/yZTdgF4kFgs/r4L2wJ5Mme1Nj65RXvg1/8TCSWoL/VhfpIbC/pvze0er+l9RZ7bfF5WiTlnlF7C222SZNOXvsppukYQEYigEIs=; 7:K7pKHx+LNVC9rqVciCDzgAPL3uDUTO0AkSG8RkBrE3an2bnc6s+aMZjsjKO0KIqa9BCacEcgnfNRi3qBTO+jv9bx2WtbM2lJ0LWji038E7hNqG6d9KdnAunczCaaajnL/qyloVCox4UMrCA4vC34lxBKqOXB8IQnia/GdfmQiUKLvq002GAbs3q3Q6vqHZSqGBwpTtUBovPx7uARuSMbYVwC+owRBH6/qpQDl7T2ihQN8V9IYulO9NWUh5ucmwYKiEgcB6i16CfWfiWEDyKvQZkYqGLGsB/ddAA5vy78hav8C+QqV+L3AS5oDLgBCHAs SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: nokia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Sep 2016 13:26:14.9907 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0701MB2544 Subject: [FFmpeg-devel] [PATCH v3 19/25] avcodec/avcodec, avformat/movenc: support embedding channel layout to stream side data 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: =?UTF-8?q?Erkki=20Sepp=C3=A4l=C3=A4?= , OZOPlayer Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Added support for passing complex channel layout configuration as side packet data (AV_PKT_DATA_AUDIO_TRACK_CHANNEL_LAYOUT) to ISO media files as specified by ISO/IEC 14496-12. AVAudioTrackChannelLayout has the fields to setting both predefined audio layouts, completely configuring the azimuth and elevation of each speaker as well as describing the number of audio objects in the scene. This information isn't integrated into the existing channel layout system though, which is much more restricted compared to what the standard permits. However, the side packet data is structured so that it does not require too much ISO base media file format knowledge in client code. In addition, it should be possible to extend the enumeration and the record to allow for using the same side data for a more native solution. The names of the channels and layouts are available in channel_layout_isoiec23001_8.h with slightly obtuse names such as AV_SPEAKER_POSITION_ISOIEC230081_8_L and AV_CH_LAYOUT_ISOIEC230081_8_1_0_0 to encourage path forward to a more native solution for FFmpeg. This channel layout information ends up to a chnl box in the written file in an isom track. Signed-off-by: Erkki Seppälä Signed-off-by: OZOPlayer --- libavcodec/avcodec.h | 71 +++++++++++++++++++++++ libavformat/movenc.c | 87 +++++++++++++++++++++++++++- libavutil/channel_layout_isoiec23001_8.h | 97 ++++++++++++++++++++++++++++++++ 3 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 libavutil/channel_layout_isoiec23001_8.h 2.7.4 diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 0079d22..7b52975 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -39,6 +39,7 @@ #include "libavutil/log.h" #include "libavutil/pixfmt.h" #include "libavutil/rational.h" +#include "libavutil/channel_layout_isoiec23001_8.h" #include "version.h" @@ -1368,6 +1369,69 @@ typedef struct AVTrackReferences { /** followed by an optional gap for alignment purposes and another AVTrackReferences is applicaple */ } AVTrackReferences; +/** + * Describes the speaker position of a single audio channel of a single track + * + * The name is chosen in a slightly obscure manner as to allow a more + * natural name to take its place when the system supports FFmpeg's + * native channel positions. + */ +typedef struct AVAudioTrackChannelPositionISOIEC23001_8 { + AVSpeakerPositionISOIEC23001_8 speaker_position; /**< an OutputChannelPosition from ISO/IEC 23001-8 */ + + /** The following are used if speaker_position == AV_SPEAKER_POSITION_ISOIEC23001_8_EXPL */ + int16_t azimuth; /**< Degrees -180..180. Values increment counterclockwise from above. */ + int8_t elevation; /**< Degrees -90..90. >0 is above horizon. */ +} AVAudioTrackChannelPositionISOIEC23001_8; + +/** + * Describes the channel layout (ie. speaker position) of a single audio track + * + * The name is chosen in a slightly obscure manner as to allow a more + * natural name to take its place when the system supports FFmpeg's + * native channel positions. + */ +typedef struct AVAudioTrackChannelCompleteLayoutISOIEC23001_8 { + int nb_positions; + AVAudioTrackChannelPositionISOIEC23001_8 positions[64]; +} AVAudioTrackChannelCompleteLayoutISOIEC23001_8; + +/** + * Describes the channel layout based on predefined layout of a single + * track by providing the layout and the list of channels are are + * omitted. For example, you may choose a layout that has 6.1 channels + * and then choose to omit the LFE channel from your channels. + * + * The name is chosen in a slightly obscure manner as to allow a more natural + * name to take its place when the system supports FFmpeg's native layouts. + */ +typedef struct AVAudioTrackChannelPredefinedLayoutISOIEC23001_8 { + AVChannelLayoutISOIEC23001_8 layout; /**< ChannelConfiguration from ISO/IEC 23001-8 */ + uint64_t omitted_channels; /**< lsb 1 means the first channel is omitted and so on */ +} AVAudioTrackChannelPredefinedLayoutISOIEC23001_8; + +typedef enum AVComplexAudioTrackChannelLayoutType { + AV_COMPLEX_CHANNEL_LAYOUT_OBJECTS_ONLY, + AV_COMPLEX_CHANNEL_LAYOUT_PREDEFINED_ISOIEC23001_8, + AV_COMPLEX_CHANNEL_LAYOUT_COMPLETE_ISOIEC23001_8, +} AVComplexAudioTrackChannelLayoutType; + +typedef struct AVAudioTrackChannelLayout { + AVComplexAudioTrackChannelLayoutType type; + union { + AVAudioTrackChannelPredefinedLayoutISOIEC23001_8 predefined; + AVAudioTrackChannelCompleteLayoutISOIEC23001_8 complete; + }; + + /** + * Describes the channel layout to be object-structured with given + * number of objects. Object-structured audio is means to describe + * an audio scene without a fixed channel layout that can be mixed + * to varying channel configurations. + */ + int nb_audio_objects; /**< Number of audio objects */ +} AVAudioTrackChannelLayout; + enum AVPacketSideDataType { AV_PKT_DATA_PALETTE, @@ -1562,6 +1626,13 @@ enum AVPacketSideDataType { AV_PKT_DATA_TIMED_METADATA_INFO, /** + * Channel layout, describing the position of spakers for the + * channels of a track, following the structure + * AVAudioTrackChannelLayout. + */ + AV_PKT_DATA_AUDIO_TRACK_CHANNEL_LAYOUT, + + /** * Assign alternate groups for tracks. An example of alternate * groups would be audio tracks (or video tracks) that are * alternative to each other. Each alternative track shares the diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 2c933d4..2543404 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -557,6 +557,89 @@ static unsigned compute_avg_bitrate(MOVTrack *track) return size * 8 * track->timescale / track->track_duration; } +static int mov_write_chnl_tag(AVIOContext *pb, MOVTrack *track) +{ + AVAudioTrackChannelLayout *side_data = + (void*) av_stream_get_side_data(track->st, AV_PKT_DATA_AUDIO_TRACK_CHANNEL_LAYOUT, + NULL); + + if (!side_data) { + return 0; + } else { + AVAudioTrackChannelPredefinedLayoutISOIEC23001_8 *predefined = + side_data && side_data->type == AV_COMPLEX_CHANNEL_LAYOUT_PREDEFINED_ISOIEC23001_8 + ? &side_data->predefined + : NULL; + + AVAudioTrackChannelCompleteLayoutISOIEC23001_8 *complete = + side_data && side_data->type == AV_COMPLEX_CHANNEL_LAYOUT_COMPLETE_ISOIEC23001_8 + ? &side_data->complete + : NULL; + + int object_count = side_data ? side_data->nb_audio_objects : 0; + + int64_t pos = avio_tell(pb); + + int channel_structured = predefined || complete; + int object_structured = !!object_count; + + // ChannelConfiguration from ISO/IEC 23001-8 + int defined_layout = predefined ? predefined->layout : 0; + int channel_count = track->par->channels; + + int stream_structure = (channel_structured << 0) | (object_structured << 1); + + if (object_count < 0 || + defined_layout < 0) + return AVERROR(EINVAL); + + avio_wb32(pb, 0); // size + ffio_wfourcc(pb, "chnl"); + avio_wb32(pb, 0); // Version + + avio_w8(pb, stream_structure); + + if (channel_structured) { + avio_w8(pb, defined_layout); + if (defined_layout == 0) { + AVAudioTrackChannelPositionISOIEC23001_8* positions; + int i; + + if (!complete) + goto error; + + if (complete->nb_positions > channel_count) + goto error; + + positions = complete->positions; + + for (i = 0; i < channel_count; ++i) { + AVAudioTrackChannelPositionISOIEC23001_8 *pos = &positions[i]; + avio_w8(pb, pos->speaker_position); + if (pos->speaker_position == AV_SPEAKER_POSITION_ISOIEC23001_8_EXPL) { + if (pos->azimuth < -180 || pos->azimuth > 180) + return AVERROR(EINVAL); + avio_wb16(pb, pos->azimuth); + avio_w8(pb, pos->elevation); + } + } + } else { + if (!predefined) + goto error; + + avio_wb64(pb, predefined->omitted_channels); + } + } + if (object_structured) + avio_w8(pb, object_count); + + return update_size(pb, pos); + error: + update_size(pb, pos); + return AVERROR(EINVAL); + } +} + static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic { AVCPBProperties *props; @@ -996,8 +1079,10 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex (mov_pcm_le_gt16(track->par->codec_id) && version==1) || (mov_pcm_be_gt16(track->par->codec_id) && version==1))) mov_write_wave_tag(s, pb, track); - else if (track->tag == MKTAG('m','p','4','a')) + else if (track->tag == MKTAG('m','p','4','a')) { + mov_write_chnl_tag(pb, track); mov_write_esds_tag(pb, track); + } else if (track->par->codec_id == AV_CODEC_ID_AMR_NB) mov_write_amr_tag(pb, track); else if (track->par->codec_id == AV_CODEC_ID_AC3) diff --git a/libavutil/channel_layout_isoiec23001_8.h b/libavutil/channel_layout_isoiec23001_8.h new file mode 100644 index 0000000..72f39c1 --- /dev/null +++ b/libavutil/channel_layout_isoiec23001_8.h @@ -0,1 +1,97 @@ +/* + * copyright (c) 2016 Erkki Seppälä + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_CHANNEL_LAYOUT_ISOIEC23001_8_H +#define AVUTIL_CHANNEL_LAYOUT_ISOIEC23001_8_H + +/** Speaker positions according to ISO/IEC 23001-8 */ +typedef enum AVSpeakerPositionISOIEC23001_8 { + AV_SPEAKER_POSITION_ISOIEC23001_8_L = 0, //< Left front + AV_SPEAKER_POSITION_ISOIEC23001_8_R = 1, //< Right front + AV_SPEAKER_POSITION_ISOIEC23001_8_C = 2, //< Centre front + AV_SPEAKER_POSITION_ISOIEC23001_8_LFE = 3, //< Low frequency enhancement + AV_SPEAKER_POSITION_ISOIEC23001_8_LS = 4, //< Left surround + AV_SPEAKER_POSITION_ISOIEC23001_8_RS = 5, //< Right surround + AV_SPEAKER_POSITION_ISOIEC23001_8_LC = 6, //< Left front centre + AV_SPEAKER_POSITION_ISOIEC23001_8_RC = 7, //< Right front centre + AV_SPEAKER_POSITION_ISOIEC23001_8_LSR = 8, //< Rear surround left + AV_SPEAKER_POSITION_ISOIEC23001_8_RSR = 9, //< Rear surround right + AV_SPEAKER_POSITION_ISOIEC23001_8_CS = 10, //< Rear centre + AV_SPEAKER_POSITION_ISOIEC23001_8_LSD = 11, //< Left surround direct + AV_SPEAKER_POSITION_ISOIEC23001_8_RSD = 12, //< Right surround direct + AV_SPEAKER_POSITION_ISOIEC23001_8_LSS = 13, //< Left side surround + AV_SPEAKER_POSITION_ISOIEC23001_8_RSS = 14, //< Right side surround + AV_SPEAKER_POSITION_ISOIEC23001_8_LW = 15, //< Left wide front + AV_SPEAKER_POSITION_ISOIEC23001_8_RW = 16, //< Right wide front + AV_SPEAKER_POSITION_ISOIEC23001_8_LV = 17, //< Left front vertical height + AV_SPEAKER_POSITION_ISOIEC23001_8_RV = 18, //< Right front vertical height + AV_SPEAKER_POSITION_ISOIEC23001_8_CV = 19, //< Centre front vertical height + AV_SPEAKER_POSITION_ISOIEC23001_8_LVR = 20, //< Left surround vertical height rear + AV_SPEAKER_POSITION_ISOIEC23001_8_RVR = 21, //< Right surround vertical height rear + AV_SPEAKER_POSITION_ISOIEC23001_8_CVR = 22, //< Centre vertical height rear + AV_SPEAKER_POSITION_ISOIEC23001_8_LVSS = 23, //< Left vertical height side surround + AV_SPEAKER_POSITION_ISOIEC23001_8_RVSS = 24, //< Right vertical height side surround + AV_SPEAKER_POSITION_ISOIEC23001_8_TS = 25, //< Top centre surround + AV_SPEAKER_POSITION_ISOIEC23001_8_LFE2 = 26, //< E2 Low frequency enhancement 2 + AV_SPEAKER_POSITION_ISOIEC23001_8_LB = 27, //< Left front vertical bottom + AV_SPEAKER_POSITION_ISOIEC23001_8_RB = 28, //< Right front vertical bottom + AV_SPEAKER_POSITION_ISOIEC23001_8_CB = 29, //< Centre front vertical bottom + AV_SPEAKER_POSITION_ISOIEC23001_8_LVS = 30, //< Left vertical height surround + AV_SPEAKER_POSITION_ISOIEC23001_8_RVS = 31, //< Right vertical height surround + //< 32-45 Reserved + AV_SPEAKER_POSITION_ISOIEC23001_8_LFE3 = 36, //< E3 Low frequency enhancement 3 + AV_SPEAKER_POSITION_ISOIEC23001_8_LEOS = 37, //< Left edge of screen + AV_SPEAKER_POSITION_ISOIEC23001_8_REOS = 38, //< Right edge of screen + AV_SPEAKER_POSITION_ISOIEC23001_8_HWBCAL = 39, //< half-way between centre of screen and left edge of screen + AV_SPEAKER_POSITION_ISOIEC23001_8_HWBCAR = 40, //< half-way between centre of screen and right edge of screen + AV_SPEAKER_POSITION_ISOIEC23001_8_LBS = 41, //< Left back surround + AV_SPEAKER_POSITION_ISOIEC23001_8_RBS = 42, //< Right back surround + //< 43–125 Reserved + AV_SPEAKER_POSITION_ISOIEC23001_8_EXPL = 126, //< Explicit position (see text) + //< 127 Unknown / undefined +} AVSpeakerPositionISOIEC23001_8; + +/** Channel layouts according to ISO/IEC 23001-8 */ +typedef enum AVChannelLayoutISOIEC23001_8 { + AV_CH_LAYOUT_ISOIEC23001_8_ANY, + AV_CH_LAYOUT_ISOIEC23001_8_1_0_0, //< 1 centre front + AV_CH_LAYOUT_ISOIEC23001_8_2_0_0, //< 2 left front, right front + AV_CH_LAYOUT_ISOIEC23001_8_3_0_0, //< 3 centre front, left front, right front + AV_CH_LAYOUT_ISOIEC23001_8_3_1_0, //< 4 centre front, left front, right front, rear centre + AV_CH_LAYOUT_ISOIEC23001_8_3_2_0, //< 5 centre front, left front, right front, left surround, right surround + AV_CH_LAYOUT_ISOIEC23001_8_3_2_1, //< 6 centre front, left front, right front, left surround, right surround, LFE + AV_CH_LAYOUT_ISOIEC23001_8_5_2_1A, //< 7 centre front, left front centre, right front centre, left front, right front, left surround, right surround, LFE + AV_CH_LAYOUT_ISOIEC23001_8_1P1, //< 8 channel1 channel2 + AV_CH_LAYOUT_ISOIEC23001_8_2_1_0, //< 9 left front, right front, rear centre + AV_CH_LAYOUT_ISOIEC23001_8_2_2_0, //< 10 left front, right front, left surround, right surround + AV_CH_LAYOUT_ISOIEC23001_8_3_3_1, //< 11 centre front, left front, right front, left surround, right surround, rear centre, LFE + AV_CH_LAYOUT_ISOIEC23001_8_3_4_1, //< 12 centre front, left front, right front, left surround, right surround, rear surround left, rear surround right, LFE + AV_CH_LAYOUT_ISOIEC23001_8_11_11_2, //< 13 centre front, left front centre, right front centre, left front, right front, left side surround, right side surround, rear left surround, rear right surround, rear centre, left front LFE, right front LFE, centre front vertical height, left front vertical height, right front vertical height, left vertical height side surround, r ight vertical height side surround, top centre surround, left surround vertical height rear, r ight surround vertical height rear , centre vertical height rear, centre front vertical bottom, left front vertical bottom, right front vertical bottom + AV_CH_LAYOUT_ISOIEC23001_8_5_2_1B, //< 14 centre front, left front, right front, left surround, right surround, LFE, left front vertical height, right front vertical height + AV_CH_LAYOUT_ISOIEC23001_8_5_5_2, //< 15 centre front, left front, right front, left side surround, right side surround, left surround, right surround, left front vertical height, right front vertical height, centre vertical height rear, LFE1, LFE2 + AV_CH_LAYOUT_ISOIEC23001_8_5_4_1, //< 16 centre front, left front, right front, left surround, right surround, LFE, left front vertical height, right front vertical height, left vertical height surround, right vertical height surround + AV_CH_LAYOUT_ISOIEC23001_8_6_5_1, //< 17 centre front, left front, right front, left surround, right surround, LFE, left front vertical height, right front vertical height, centre front vertical height, left vertical height surround, right vertical height surround, top centre surround + AV_CH_LAYOUT_ISOIEC23001_8_6_7_1, //< 18 centre front, left front, right front, left surround, right surround, left back surround, right back surround LFE, left front vertical height, right front vertical height, centre front vertical height, left vertical height surround, right vertical height surround, top centre surround + AV_CH_LAYOUT_ISOIEC23001_8_5_6_1, //< 19 centre front, left front, right front, left side surround, right side surround, rear surround left, rear surround right, LFE, left front vertical height, right front vertical height, left surround vertical height rear, right surround vertical height rear + AV_CH_LAYOUT_ISOIEC23001_8_7_6_1, //< 20 centre front, left edge of screen, right edge of screen, left front, right front, left side surround, right side surround, rear surround left, rear surround right, LFE, left front vertical height, right front vertical height, left vertical height surround, right vertical height surround + //< 21..63: reserved +} AVChannelLayoutISOIEC23001_8; + +#endif /* AVUTIL_CHANNEL_LAYOUT_ISOIEC23001_8_H */ --