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 675C14DF61 for ; Thu, 5 Jun 2025 23:07:47 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id 8398768D1C5; Fri, 6 Jun 2025 02:07:43 +0300 (EEST) Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05olkn2036.outbound.protection.outlook.com [40.92.89.36]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id 5E35E68B912 for ; Fri, 6 Jun 2025 02:07:37 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=joJQnHgjeICBpF7OVG9WL99otNOGTNb0Arsp8IXo7D8wFf1t1+BMWBl6tPx0oJtaCiJihm9dMuevFX7gJSMe1ipESX6v0Ili/0/wP8KbjSBRLbJ7Cwsjv/oAwv/yuj9LOj7mTRINcFt4MqTXaXi++dNwDpo/PDiz0wYkvEH1PGlaWiz4pydpSwS2Qyl6k6huJtPwJxC8yoxP1OMnvPbGe5m/3Mr/dBBy33ucScKCO+0Rrh74BnuJMjLTgH7tZP6m7mkk7AG/xk1Az7OKk3YAIgeA0SnjLAkfL0M62PyK8XAkZAPAf8OOhElj8HhWvr1w0RShF8gS6RBH4ZV+PY5TqA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Pyf2dYsLVOheIN5iaeFoifK3YBEJ9lW8QdwzeBXks2E=; b=w9lJ5QMoCZ/z01qQTzhwYbJ/rXx8hB2RBexZGPuiYHiu7swwkfgWJUqNhVpc54hV9KOlm8L4iW2wNq4xvZVaAxnczZ2wFjZLD5s08/RgJALuQnx2sPl3EaEE7a+5Pv3eAJdMHLpVU4o3VZr4+49bXjdfWjk3Rm3fLqJ1Hr4iGo7lSN+kjrOZ5Fw5L3qdz5vE3HwQA3lJc9zBh6DFlJo5Ab1nRNC3D/kv/rKwbv/8ObjcAsL+HxCqquFsU7ZHZYmkgzpBMthXEq8+CDQPl5w7Ak2JVmlPDMxM5AyYh1RHsDASMCLr4+RHuYOsMua/mAeSrSyn1pFDnFwsD0H1ofDu8Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=outlook.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Pyf2dYsLVOheIN5iaeFoifK3YBEJ9lW8QdwzeBXks2E=; b=Wf6zc9QPnpCPzrkqly1b7VnE+cg7102FEnUXXPBjqJF2ErigTT5eiVsfaZlTtlKSHZEmzyjsotOvk2/Rc+ZnGpJZsu2q7kCaCzbKxKsXaNDR8NqW/csjQR7+l79zs9YGi2P4H4it3+NukQpmrig9WA5auCE5SRdi8dLFeim5xhKT7AffLzyja/ljSl/UcYOV01AxV/qrqLQsQV9p++2YgOyI/FRz7Kta8iNlK0/x/CzMX3PK5H7H798LVAnppWqogHu5vlQbQnXh9LGWGSzOZRIz+B8KSppr68re7L6AOFUNauOU11pEk/VOnjT/9gmmYfPhrHnq9Jic2RfvVHnSjw== Received: from GV1P250MB0737.EURP250.PROD.OUTLOOK.COM (2603:10a6:150:8e::17) by AS1P250MB0454.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:4a8::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8792.34; Thu, 5 Jun 2025 23:07:35 +0000 Received: from GV1P250MB0737.EURP250.PROD.OUTLOOK.COM ([fe80::d6a1:e3af:a5f1:b614]) by GV1P250MB0737.EURP250.PROD.OUTLOOK.COM ([fe80::d6a1:e3af:a5f1:b614%5]) with mapi id 15.20.8792.034; Thu, 5 Jun 2025 23:07:35 +0000 Message-ID: Date: Fri, 6 Jun 2025 01:07:32 +0200 User-Agent: Mozilla Thunderbird To: ffmpeg-devel@ffmpeg.org References: <20250605214938.142938-1-jamrial@gmail.com> Content-Language: en-US From: Andreas Rheinhardt In-Reply-To: <20250605214938.142938-1-jamrial@gmail.com> X-ClientProxiedBy: OS6P279CA0162.NORP279.PROD.OUTLOOK.COM (2603:10a6:e10:39::6) To GV1P250MB0737.EURP250.PROD.OUTLOOK.COM (2603:10a6:150:8e::17) X-Microsoft-Original-Message-ID: <96c79bf9-0cca-4a11-915e-9a56d9f65fa7@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV1P250MB0737:EE_|AS1P250MB0454:EE_ X-MS-Office365-Filtering-Correlation-Id: 39c19656-5627-4875-ccdc-08dda485c1ed X-MS-Exchange-SLBlob-MailProps: AZnQBsB9XmreLwtPaBeZFVOxwxOMrlAgm3IY5KQ6GHcTzfeUCgf7dd7rdS8mXTJ5JPvGPnuihyVN6Zwa2JmSNg4Wn5TgxOc9wEqvisaRJ0DHw693ZBJDloeAUUiyztDmFJJle1gm9NZdMTbXioeDGZ67a4UeVPb9qx1sPDMxeLtuWHHiwt6aWVD2aoD9lxHKfFC8yCUiOyPnh6t3QTBAEYpn1/ascLmfL4bcQlmmPs2jinesmdNK6+PSXWGEhKzsdX8u+C87bKsQluT6V9kOSM7cjWP7Sl+LpJHj5OohgyGtBnpPCJymGZZ0wzGwe8qo+afsIXbxP+FNA9WRGgYIN9XMHNxpcPboWxa9GhrLmAlzhEVdHyXUA4+NmSqDgE8HgVdHZk6XLn5oShlwsfwIFFqJ8dtyMXSeu1Bf/Ex7R6fXC3lpIavGJJzM9kSZLhB8YO2gtx8XyrRSva4k/2cNGOcjn1jbU4z/SsKUFrEJhjEPli4GDFferNXZ/xulqA1yzSSIbsd0myl/SwHlJm4PrxmR+dZ3+Qdk+9kGrG64Eyjxgcq/CcGYc5fFXk24fPL2Hu4Lc+IuLC287t7P9QdHEfL6hyzpwbsTWLm+M0nvW7BR2HSccuXO+ZtSC8snbSJOzzJHF8pQeVj4WLtdFzgc8zqeTVmAR2H8aEi5fBq6g0NBgotWxiGeSu7tk4B6JIQ1MQNtGwqsa0HT3IJBaAMQD6IspCWU4bYBrCPiJnY8iaCjcwaKdL8VhzFGKjQDJxSGQygM6wY1Tk4= X-Microsoft-Antispam: BCL:0; ARA:14566002|15080799009|41001999006|8060799009|5072599009|7092599006|6090799003|19110799006|461199028|56899033|3412199025|440099028; X-Microsoft-Antispam-Message-Info: =?utf-8?B?VjFIKzBZVHFZVnhJMEp0ZHAxTHdGd2FFV3BIT0ZRS241OFZqeDc2Vko1citW?= =?utf-8?B?bXFaRGp2ZlgvU25vWmVQRmNNVXFXQWR2L3FUM2hyNWVYaGt4ZHd5MzhUcEZ5?= =?utf-8?B?dkhVRzJ4T1pXcmM1V1FGanpUL1RxaC9COWZZUEhQLys2SjhWeFpPdUJFNTNE?= =?utf-8?B?TU8wKzR6dE1PcVNMbk5GVDkzQm42aVB4UlpRazZDRkFyWXdSS1JHV1JicDMw?= =?utf-8?B?YXZpOWR3Q2Y3VUYrVFh4bHUwM21wU2VMQ1ZPT2UwVkY4cDFHRlh1dEY2QXBk?= =?utf-8?B?ekg4UFVpdWM0dDRsQTBmdmRNU3RmaGQ3aWRQQ0NhQ05MbUUvZzlYTFl5SzNH?= =?utf-8?B?TEVaM0I1aUZzUnYvN3cyT0VtY2xuTitKb0tYS0hVcXhnampOV1QrTkRwWTNa?= =?utf-8?B?a2dDdVU1OUxMVWNkTHdPRE54R3VHOTUrNnZqNmx5VmZZdzRBVy9HZVZPTjJB?= =?utf-8?B?cU1VVXdBTGhIYlR3YTlmcGFCQ2oyemlFRWlObm9VbDE5Qkhock9PenpuNGxL?= =?utf-8?B?NGVxU0RualByQkNjTU91R3NsNGUreEJwRDM5QWVZVzhXdWlWc01CNHlYSEpI?= =?utf-8?B?N1kxaFhEUGNyMmNHNkFtb1Q2MmUzaXJITUNHbXpCZisxSFJPMjdqakRvL0Ex?= =?utf-8?B?c3dDdDFWVWFRZmwyTzZDZWZ0UTRSY3FpVG5zb3hnRWdodFdpdXF0SlptZW5x?= =?utf-8?B?RC8wMXFBVG1ac3dLb0p1RktDNE44NmU0eU5yaTg3QTZjcDNGNWJMMk4zazVm?= =?utf-8?B?ZUlvNlBJN0lZS2RZZUpZcFRVZU9sS2V3T3VkR3B1S3U2Q1VpMEVycjhVSHlC?= =?utf-8?B?R3Z2Q0oxMURONjVHQWhrdFNrdEJsNUhudjdKN3JSS1kvOStRdkt3eldiZGhG?= =?utf-8?B?Rm9RTmlEalBVbDBCY2lWQ0JodlNEQ1JmeFNWKzdSeFBvc2o0eEVXaVV5VXBF?= =?utf-8?B?bmVVNTd1dXltTTdlM3ZwZFVWYzNmN3JVY3hKRjlNQXVBeUJXRVIrbDBlZEVu?= =?utf-8?B?ZmFhWFNwMVk5cTNWcVRtVmdzeTRvcXM2Wjh5aVRmVEs4QUZmRHVDR3dpZm9W?= =?utf-8?B?REhzbXdqcnVTa3ZoMjdvSlhKY005c3E1UkQ0cEhzSENjQXRjbGJKNnBRMTVJ?= =?utf-8?B?cU51bkYwbWVUeERTdVFJNEdPTmxXWnUxRnIvZDFEc1VPbDNJZ2dOZlhLYlRM?= =?utf-8?B?NlBNYndVRUhBZmlQNmFKQXg5TnJNRHFOQnYyTXJvcTBFY29vMnpJc3FUSVkx?= =?utf-8?B?SHNGZUlHL1U4R1VLOFppMUZtbm9xOUlkcG1La3oxQ2FGWlYzSFl0TTJJb0pL?= =?utf-8?B?dEZrbHQva1JTbU15eFRjV0Jxa3dZRERUQWxqODkwdS9namdIdmZNb2YvSTFF?= =?utf-8?B?bFluNzUxMjZ4K2hsT1d2SlQ0VC9ScldzVXhFa3AzN0Jna1BSQ2VHeVY2eG02?= =?utf-8?B?dnBZQm9QMDVuQmg0TGx5QjdoaXpXQmxxZ1JRS0tnS0ZiU1BTQ3hkYzkwL3Zn?= =?utf-8?B?cDJKdytWclBYajFtK3gvSXNlWDlJZ1FwN1Q1S1Q2bWxwNXZwSnY1K1N5T1J6?= =?utf-8?Q?COnqAsX42jGXGmRFdGRC+i4Xg=3D?= X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?OTNCRklpeVZOZzVMd3dOM1N0cmdySUo5STJ1ekNkUEI1ci9TcVlNYUNleW9J?= =?utf-8?B?MTViLzV0ZTluVmgvekFFYVM1UGNEWnp6L0lKelFoSVArMWVyTjVLNUNTSG5D?= =?utf-8?B?WEVCaksrVmJRZHYxckVmcXFrWjhlMEwyREJWTVhVVzJqa2cyMG5GbE5HRTA3?= =?utf-8?B?Vi95bDVMSVRVWHR2ckRwOEpmQXVoYXVyWVFuaEZ4czZJRFprbElSOWdjSTlp?= =?utf-8?B?bitmSnFJVW84Q2ltYjYrWnlGRFJjb25mOTE0cXEvc2NKR3R2QVp0NjN1NzlO?= =?utf-8?B?ZlZ2MzUraklPK01yYnF4Sy9LbHROY2JJOWlEOHVtYWQ4UDNBZUwwcVlrYVF4?= =?utf-8?B?TnlEU0hQaGRGYmtJM1lJb3YzcmIrV1VITkI5UVIwSVhWM3kzWnBVUERsSHB4?= =?utf-8?B?T2tSbFJoL0lUZFFpbzJVQnRodWlsRFZMM0JZOER2U0JuOXllb2VIRXZvejYx?= =?utf-8?B?R0owQ3pzTHN4Y0ZjUXZac1gzWnF3aERaTzVUYTR2Sm9pNjRkQ1g5Tmh0bU83?= =?utf-8?B?a1pUL25FSTBUOGlmaUQ2eERITGN6T1VoTHVBMTZWM3pTd0trbG4xWmJ0QnM0?= =?utf-8?B?cDVvYVpEbmNVVmp2L29WYzhTVVBPZlVMV1dNaDBIYktWNGZvTTlXRVRrWXUy?= =?utf-8?B?SjRDZkVwYUd4K0RkUi8yTHZGOWZXUk5Lc1pQL2l3TXBNWTZ5M3JvTVVFTHh3?= =?utf-8?B?NkloY1NIR0hEc2NXNWxvYktLNURIWUpHaktJMTNVZExOYmtoZDFURzZBWUg5?= =?utf-8?B?T1NTakF4akgrWjd6OUROYnJ0QmNMUW5QcW1rNVp5TFBlR0dRU29qM0Qrc0hl?= =?utf-8?B?SER4K3JXQlZnVFZTZWZHc2pOa010eXpoeXd4bjhDZHptTFhrQWpPT0xwTHZo?= =?utf-8?B?eUcwc0Z6UzBVdy9sRTlUOWFJZ1lRNFBUZzd6TVJST05rM1lQT0JFcHYzellm?= =?utf-8?B?dTJreVdSaEpOamZlTVpXeC9sRlZaVDFudnU5Qzcxd2Jva1JCRUsxMkhZNVhv?= =?utf-8?B?QUZ2TXBqOUhyR0hSR3JxbzNuS2tPRjNlZ0hnN1VLbFFza0NYb1FtVzVTQnRs?= =?utf-8?B?bldKVGEzcGhkVTk4bkV6V1Z6SUJFNERaUnkyM0ttaVNKZmtKK09nSTlKSm9u?= =?utf-8?B?Y0dUSGpHUVZHb3pGTmJXU0tFdi9MOFRnOTdmQjVKSE91cDZoMi9IbzE5SHZs?= =?utf-8?B?RUx5YjMzRk1JWHVXNHcwNjNPMno5VDJrVWlKak4wemZEbVgxcVQwMmVWV2p1?= =?utf-8?B?SDBFN3lwS1orZ1U5UEZwRzRiY253V2JMcXBMRUJSb2RFbTMyL2F0cXdaaWph?= =?utf-8?B?M0ZzdVdzRm5NdFgvSC9NS1hDMkNGdW1ETjhUOWZQM1FuSmlVcXdRZzA3QUxI?= =?utf-8?B?U2N6VzZvMUtmcEtMZm9DczEwVWtwSHV0aWVDbmdXWVFuUGZQVTJ0cWxPR3VD?= =?utf-8?B?QVBZaG5jdE0zeWJLaXQwa1gyblpMK2ZkdTR5MmdvT3l0blJZNno3WWt1cDFa?= =?utf-8?B?TFpkN1lIeWM0dTREV2dLTWx6Z2NSL2c4ZWhtWk5iT0pqK0FOenZQMGZ0ajlw?= =?utf-8?B?R0NiNXZld1lJbDJuL04yb2dGVWRoclZvN2xjczlvSndXWnZlS0FxVTRNNWJG?= =?utf-8?B?a2pacE9ET2dpbXZlbTdpMDAxNU5LeG1SSWluY3pRVUJHRFZqRk9YamlCYW5F?= =?utf-8?B?T2Q3VU9nYm51TWp5RWh3RVlVbS9KSUZsZ3RpekRneWFtazd2YWlSNXJ3RlZJ?= =?utf-8?B?RTlOY1VVY2x0dlo5bUl6N0pxMzhGbEJCa0FqMExXQ1lWNjFWYUUwNlIvYkl5?= =?utf-8?B?Q1RNeVMyZVlJSk4vSm9yUT09?= X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 39c19656-5627-4875-ccdc-08dda485c1ed X-MS-Exchange-CrossTenant-AuthSource: GV1P250MB0737.EURP250.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Jun 2025 23:07:35.1924 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS1P250MB0454 Subject: Re: [FFmpeg-devel] [PATCH 1/3] avcodec/ac3_parser: handle more header bits in ff_ac3_parse_header() 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: James Almer: > Signed-off-by: James Almer > --- > libavcodec/ac3_parser.c | 218 +++++++++++++++++++++++++++++++ > libavcodec/ac3_parser_internal.h | 19 +++ > libavcodec/ac3dec.c | 88 +++---------- > libavcodec/ac3dec.h | 4 +- > libavcodec/ac3defs.h | 2 + > libavcodec/eac3dec.c | 154 +++------------------- > 6 files changed, 279 insertions(+), 206 deletions(-) > > diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c > index 69989690dd..1cba847eaa 100644 > --- a/libavcodec/ac3_parser.c > +++ b/libavcodec/ac3_parser.c > @@ -73,6 +73,216 @@ int ff_ac3_find_syncword(const uint8_t *buf, int buf_size) > return i; > } > > +/** > + * Parse the 'sync info' and 'bit stream info' from the AC-3 bitstream. > + * GetBitContext within AC3DecodeContext must point to > + * the start of the synchronized AC-3 bitstream. > + */ > +static int ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) > +{ > + /* read the rest of the bsi. read twice for dual mono mode. */ > + for (int i = 0; i < (hdr->channel_mode ? 1 : 2); i++) { > + hdr->dialog_normalization[i] = -get_bits(gbc, 5); > + hdr->compression_exists[i] = get_bits1(gbc); > + if (hdr->compression_exists[i]) > + hdr->heavy_dynamic_range[i] = get_bits(gbc, 8); > + if (get_bits1(gbc)) > + skip_bits(gbc, 8); //skip language code > + if (get_bits1(gbc)) > + skip_bits(gbc, 7); //skip audio production information > + } > + > + skip_bits(gbc, 2); //skip copyright bit and original bitstream bit > + > + /* skip the timecodes or parse the Alternate Bit Stream Syntax */ > + if (hdr->bitstream_id != 6) { > + if (get_bits1(gbc)) > + skip_bits(gbc, 14); //skip timecode1 > + if (get_bits1(gbc)) > + skip_bits(gbc, 14); //skip timecode2 > + } else { > + if (get_bits1(gbc)) { > + hdr->preferred_downmix = get_bits(gbc, 2); > + hdr->center_mix_level_ltrt = get_bits(gbc, 3); > + hdr->surround_mix_level_ltrt = av_clip(get_bits(gbc, 3), 3, 7); > + hdr->center_mix_level = get_bits(gbc, 3); > + hdr->surround_mix_level = av_clip(get_bits(gbc, 3), 3, 7); > + } > + if (get_bits1(gbc)) { > + hdr->dolby_surround_ex_mode = get_bits(gbc, 2); > + hdr->dolby_headphone_mode = get_bits(gbc, 2); > + skip_bits(gbc, 10); // skip adconvtyp (1), xbsi2 (8), encinfo (1) > + } > + } > + > + /* skip additional bitstream info */ > + if (get_bits1(gbc)) { > + int i = get_bits(gbc, 6); > + do { > + skip_bits(gbc, 8); > + } while (i--); > + } > + > + return 0; > +} > + > +static int eac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) > +{ > + if (hdr->frame_type == EAC3_FRAME_TYPE_RESERVED) > + return AC3_PARSE_ERROR_FRAME_TYPE; > + if (hdr->substreamid) > + return AC3_PARSE_ERROR_FRAME_TYPE; > + > + skip_bits(gbc, 5); // skip bitstream id > + > + /* volume control params */ > + for (int i = 0; i < (hdr->channel_mode ? 1 : 2); i++) { > + hdr->dialog_normalization[i] = -get_bits(gbc, 5); > + hdr->compression_exists[i] = get_bits1(gbc); > + if (hdr->compression_exists[i]) > + hdr->heavy_dynamic_range[i] = get_bits(gbc, 8); > + } > + > + /* dependent stream channel map */ > + if (hdr->frame_type == EAC3_FRAME_TYPE_DEPENDENT) { > + if (get_bits1(gbc)) { > + int64_t channel_layout = 0; > + int channel_map = get_bits(gbc, 16); > + > + for (int i = 0; i < 16; i++) > + if (channel_map & (1 << (EAC3_MAX_CHANNELS - i - 1))) > + channel_layout |= ff_eac3_custom_channel_map_locations[i][1]; > + > + if (av_popcount64(channel_layout) > EAC3_MAX_CHANNELS) { > + return AC3_PARSE_ERROR_CHANNEL_MAP; > + } > + hdr->channel_map = channel_map; > + } > + } > + > + /* mixing metadata */ > + if (get_bits1(gbc)) { > + /* center and surround mix levels */ > + if (hdr->channel_mode > AC3_CHMODE_STEREO) { > + hdr->preferred_downmix = get_bits(gbc, 2); > + if (hdr->channel_mode & 1) { > + /* if three front channels exist */ > + hdr->center_mix_level_ltrt = get_bits(gbc, 3); > + hdr->center_mix_level = get_bits(gbc, 3); > + } > + if (hdr->channel_mode & 4) { > + /* if a surround channel exists */ > + hdr->surround_mix_level_ltrt = av_clip(get_bits(gbc, 3), 3, 7); > + hdr->surround_mix_level = av_clip(get_bits(gbc, 3), 3, 7); > + } > + } > + > + /* lfe mix level */ > + if (hdr->lfe_on && (hdr->lfe_mix_level_exists = get_bits1(gbc))) { > + hdr->lfe_mix_level = get_bits(gbc, 5); > + } > + > + /* info for mixing with other streams and substreams */ > + if (hdr->frame_type == EAC3_FRAME_TYPE_INDEPENDENT) { > + for (int i = 0; i < (hdr->channel_mode ? 1 : 2); i++) { > + // TODO: apply program scale factor > + if (get_bits1(gbc)) { > + skip_bits(gbc, 6); // skip program scale factor > + } > + } > + if (get_bits1(gbc)) { > + skip_bits(gbc, 6); // skip external program scale factor > + } > + /* skip mixing parameter data */ > + switch(get_bits(gbc, 2)) { > + case 1: skip_bits(gbc, 5); break; > + case 2: skip_bits(gbc, 12); break; > + case 3: { > + int mix_data_size = (get_bits(gbc, 5) + 2) << 3; > + skip_bits_long(gbc, mix_data_size); > + break; > + } > + } > + /* skip pan information for mono or dual mono source */ > + if (hdr->channel_mode < AC3_CHMODE_STEREO) { > + for (int i = 0; i < (hdr->channel_mode ? 1 : 2); i++) { > + if (get_bits1(gbc)) { > + /* note: this is not in the ATSC A/52B specification > + reference: ETSI TS 102 366 V1.1.1 > + section: E.1.3.1.25 */ > + skip_bits(gbc, 8); // skip pan mean direction index > + skip_bits(gbc, 6); // skip reserved paninfo bits > + } > + } > + } > + /* skip mixing configuration information */ > + if (get_bits1(gbc)) { > + for (int i = 0; i < hdr->num_blocks; i++) { > + if (hdr->num_blocks == 1 || get_bits1(gbc)) { > + skip_bits(gbc, 5); > + } > + } > + } > + } > + } > + > + /* informational metadata */ > + if (get_bits1(gbc)) { > + hdr->bitstream_mode = get_bits(gbc, 3); > + skip_bits(gbc, 2); // skip copyright bit and original bitstream bit > + if (hdr->channel_mode == AC3_CHMODE_STEREO) { > + hdr->dolby_surround_mode = get_bits(gbc, 2); > + hdr->dolby_headphone_mode = get_bits(gbc, 2); > + } > + if (hdr->channel_mode >= AC3_CHMODE_2F2R) { > + hdr->dolby_surround_ex_mode = get_bits(gbc, 2); > + } > + for (int i = 0; i < (hdr->channel_mode ? 1 : 2); i++) { > + if (get_bits1(gbc)) { > + skip_bits(gbc, 8); // skip mix level, room type, and A/D converter type > + } > + } > + if (hdr->sr_code != EAC3_SR_CODE_REDUCED) { > + skip_bits1(gbc); // skip source sample rate code > + } > + } > + > + /* converter synchronization flag > + If frames are less than six blocks, this bit should be turned on > + once every 6 blocks to indicate the start of a frame set. > + reference: RFC 4598, Section 2.1.3 Frame Sets */ > + if (hdr->frame_type == EAC3_FRAME_TYPE_INDEPENDENT && hdr->num_blocks != 6) { > + skip_bits1(gbc); // skip converter synchronization flag > + } > + > + /* original frame size code if this stream was converted from AC-3 */ > + if (hdr->frame_type == EAC3_FRAME_TYPE_AC3_CONVERT && > + (hdr->num_blocks == 6 || get_bits1(gbc))) { > + skip_bits(gbc, 6); // skip frame size code > + } > + > + /* additional bitstream info */ > + if (get_bits1(gbc)) { > + int addbsil = get_bits(gbc, 6); > + for (int i = 0; i < addbsil + 1; i++) { > + if (i == 0) { > + /* In this 8 bit chunk, the LSB is equal to flag_ec3_extension_type_a > + which can be used to detect Atmos presence */ > + skip_bits(gbc, 7); > + hdr->eac3_extension_type_a = get_bits1(gbc); > + if (hdr->eac3_extension_type_a) { > + hdr->complexity_index_type_a = get_bits(gbc, 8); > + i++; > + } > + } else { > + skip_bits(gbc, 8); // skip additional bit stream info > + } > + } > + } > + > + return 0; > +} > + > int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) > { > int frame_size_code; > @@ -133,6 +343,10 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) > hdr->frame_size = ff_ac3_frame_size_tab[frame_size_code][hdr->sr_code] * 2; > hdr->frame_type = EAC3_FRAME_TYPE_AC3_CONVERT; //EAC3_FRAME_TYPE_INDEPENDENT; > hdr->substreamid = 0; > + > + int ret = ac3_parse_header(gbc, hdr); > + if (ret < 0) > + return ret; > } else { > /* Enhanced AC-3 */ > hdr->crc1 = 0; > @@ -165,6 +379,10 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) > hdr->bit_rate = 8LL * hdr->frame_size * hdr->sample_rate / > (hdr->num_blocks * 256); > hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on; > + > + int ret = eac3_parse_header(gbc, hdr); > + if (ret < 0) > + return ret; > } > hdr->channel_layout = ff_ac3_channel_layout_tab[hdr->channel_mode]; > if (hdr->lfe_on) > diff --git a/libavcodec/ac3_parser_internal.h b/libavcodec/ac3_parser_internal.h > index 46814bfb1f..ab5df34003 100644 > --- a/libavcodec/ac3_parser_internal.h > +++ b/libavcodec/ac3_parser_internal.h > @@ -46,6 +46,7 @@ typedef struct AC3HeaderInfo { > int substreamid; ///< substream identification > int center_mix_level; ///< Center mix level index > int surround_mix_level; ///< Surround mix level index > + uint8_t channel_map_present; > uint16_t channel_map; > int num_blocks; ///< number of audio blocks > int dolby_surround_mode; > @@ -62,6 +63,23 @@ typedef struct AC3HeaderInfo { > uint64_t channel_layout; > int8_t ac3_bit_rate_code; > /** @} */ > + > + /** @name enhanced eac3 extension coded elements > + * @{ > + */ > + int8_t dialog_normalization[2]; > + uint8_t compression_exists[2]; > + uint8_t heavy_dynamic_range[2]; > + uint8_t center_mix_level_ltrt; ///< Center mix level index > + uint8_t surround_mix_level_ltrt; ///< Surround mix level index > + uint8_t dolby_headphone_mode; > + uint8_t dolby_surround_ex_mode; > + uint8_t lfe_mix_level_exists; > + uint8_t lfe_mix_level; > + uint8_t preferred_downmix; > + uint8_t eac3_extension_type_a; > + uint8_t complexity_index_type_a; > + /** @} */ > } AC3HeaderInfo; > > typedef enum { > @@ -71,6 +89,7 @@ typedef enum { > AC3_PARSE_ERROR_FRAME_SIZE = -0x4030c0a, > AC3_PARSE_ERROR_FRAME_TYPE = -0x5030c0a, > AC3_PARSE_ERROR_CRC = -0x6030c0a, > + AC3_PARSE_ERROR_CHANNEL_MAP = -0x7030c0a, > } AC3ParseError; > > /** > diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c > index 5eacab4475..2f0e7f5344 100644 > --- a/libavcodec/ac3dec.c > +++ b/libavcodec/ac3dec.c > @@ -156,72 +156,6 @@ static av_cold void ac3_decode_flush(AVCodecContext *avctx) > av_lfg_init(&s->dith_state, 0); > } > > -/** > - * Parse the 'sync info' and 'bit stream info' from the AC-3 bitstream. > - * GetBitContext within AC3DecodeContext must point to > - * the start of the synchronized AC-3 bitstream. > - */ > -static int ac3_parse_header(AC3DecodeContext *s) > -{ > - GetBitContext *gbc = &s->gbc; > - int i; > - > - /* read the rest of the bsi. read twice for dual mono mode. */ > - i = !s->channel_mode; > - do { > - s->dialog_normalization[(!s->channel_mode)-i] = -get_bits(gbc, 5); > - if (s->dialog_normalization[(!s->channel_mode)-i] == 0) { > - s->dialog_normalization[(!s->channel_mode)-i] = -31; > - } > - if (s->target_level != 0) { > - s->level_gain[(!s->channel_mode)-i] = powf(2.0f, > - (float)(s->target_level - > - s->dialog_normalization[(!s->channel_mode)-i])/6.0f); > - } > - if (s->compression_exists[(!s->channel_mode)-i] = get_bits1(gbc)) { > - s->heavy_dynamic_range[(!s->channel_mode)-i] = > - AC3_HEAVY_RANGE(get_bits(gbc, 8)); > - } > - if (get_bits1(gbc)) > - skip_bits(gbc, 8); //skip language code > - if (get_bits1(gbc)) > - skip_bits(gbc, 7); //skip audio production information > - } while (i--); > - > - skip_bits(gbc, 2); //skip copyright bit and original bitstream bit > - > - /* skip the timecodes or parse the Alternate Bit Stream Syntax */ > - if (s->bitstream_id != 6) { > - if (get_bits1(gbc)) > - skip_bits(gbc, 14); //skip timecode1 > - if (get_bits1(gbc)) > - skip_bits(gbc, 14); //skip timecode2 > - } else { > - if (get_bits1(gbc)) { > - s->preferred_downmix = get_bits(gbc, 2); > - s->center_mix_level_ltrt = get_bits(gbc, 3); > - s->surround_mix_level_ltrt = av_clip(get_bits(gbc, 3), 3, 7); > - s->center_mix_level = get_bits(gbc, 3); > - s->surround_mix_level = av_clip(get_bits(gbc, 3), 3, 7); > - } > - if (get_bits1(gbc)) { > - s->dolby_surround_ex_mode = get_bits(gbc, 2); > - s->dolby_headphone_mode = get_bits(gbc, 2); > - skip_bits(gbc, 10); // skip adconvtyp (1), xbsi2 (8), encinfo (1) > - } > - } > - > - /* skip additional bitstream info */ > - if (get_bits1(gbc)) { > - i = get_bits(gbc, 6); > - do { > - skip_bits(gbc, 8); > - } while (i--); > - } > - > - return 0; > -} > - > /** > * Common function to parse AC-3 or E-AC-3 frame header > */ > @@ -281,10 +215,25 @@ static int parse_frame_header(AC3DecodeContext *s) > s->dba_syntax = 1; > s->skip_syntax = 1; > memset(s->channel_uses_aht, 0, sizeof(s->channel_uses_aht)); > - return ac3_parse_header(s); > + /* volume control params */ > + for (int i = 0; i < (s->channel_mode ? 1 : 2); i++) { > + s->dialog_normalization[i] = hdr.dialog_normalization[i]; > + if (s->dialog_normalization[i] == 0) { > + s->dialog_normalization[i] = -31; > + } > + if (s->target_level != 0) { > + s->level_gain[i] = powf(2.0f, > + (float)(s->target_level - s->dialog_normalization[i])/6.0f); > + } > + s->compression_exists[i] = hdr.compression_exists[i]; > + if (s->compression_exists[i]) { > + s->heavy_dynamic_range[i] = AC3_HEAVY_RANGE(hdr.heavy_dynamic_range[i]); > + } > + } > + return 0; > } else if (CONFIG_EAC3_DECODER) { > s->eac3 = 1; > - return ff_eac3_parse_header(s); > + return ff_eac3_parse_header(s, &hdr); > } else { > av_log(s->avctx, AV_LOG_ERROR, "E-AC-3 support not compiled in\n"); > return AVERROR(ENOSYS); > @@ -1469,6 +1418,9 @@ dependent_frame: > av_log(avctx, AV_LOG_ERROR, "invalid frame type\n"); > } > break; > + case AC3_PARSE_ERROR_CHANNEL_MAP: > + av_log(avctx, AV_LOG_ERROR, "invalid channel map\n"); > + return AVERROR_INVALIDDATA; > case AC3_PARSE_ERROR_CRC: > break; > default: // Normal AVERROR do not try to recover. > diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h > index 4042a99b80..a099264475 100644 > --- a/libavcodec/ac3dec.h > +++ b/libavcodec/ac3dec.h > @@ -260,11 +260,13 @@ typedef struct AC3DecodeContext { > ///@} > } AC3DecodeContext; > > +struct AC3HeaderInfo; > + > /** > * Parse the E-AC-3 frame header. > * This parses both the bit stream info and audio frame header. > */ > -static int ff_eac3_parse_header(AC3DecodeContext *s); > +static int ff_eac3_parse_header(AC3DecodeContext *s, const struct AC3HeaderInfo *hdr); > > /** > * Decode mantissas in a single channel for the entire frame. > diff --git a/libavcodec/ac3defs.h b/libavcodec/ac3defs.h > index f9b1be059f..8d6a58d21f 100644 > --- a/libavcodec/ac3defs.h > +++ b/libavcodec/ac3defs.h > @@ -34,6 +34,8 @@ > #define AC3_CRITICAL_BANDS 50 > #define AC3_MAX_CPL_BANDS 18 > > +#define EAC3_SR_CODE_REDUCED 3 > + > /* pre-defined gain values */ > #define LEVEL_PLUS_3DB M_SQRT2 > #define LEVEL_PLUS_1POINT5DB 1.1892071150027209 > diff --git a/libavcodec/eac3dec.c b/libavcodec/eac3dec.c > index 2b3bffda6e..c5095b1917 100644 > --- a/libavcodec/eac3dec.c > +++ b/libavcodec/eac3dec.c > @@ -53,8 +53,6 @@ typedef enum { > EAC3_GAQ_124 > } EAC3GaqMode; > > -#define EAC3_SR_CODE_REDUCED 3 > - > static void ff_eac3_apply_spectral_extension(AC3DecodeContext *s) > { > int bin, bnd, ch, i; > @@ -287,7 +285,7 @@ static void ff_eac3_decode_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch) > } > } > > -static int ff_eac3_parse_header(AC3DecodeContext *s) > +static int ff_eac3_parse_header(AC3DecodeContext *s, const AC3HeaderInfo *hdr) > { > int i, blk, ch; > int ac3_exponent_strategy, parse_aht_info, parse_spx_atten_data; > @@ -323,11 +321,10 @@ static int ff_eac3_parse_header(AC3DecodeContext *s) > avpriv_request_sample(s->avctx, "Reduced sampling rate"); > return AVERROR_PATCHWELCOME; > } > - skip_bits(gbc, 5); // skip bitstream id > > /* volume control params */ > for (i = 0; i < (s->channel_mode ? 1 : 2); i++) { > - s->dialog_normalization[i] = -get_bits(gbc, 5); > + s->dialog_normalization[i] = hdr->dialog_normalization[i]; > if (s->dialog_normalization[i] == 0) { > s->dialog_normalization[i] = -31; > } > @@ -335,147 +332,30 @@ static int ff_eac3_parse_header(AC3DecodeContext *s) > s->level_gain[i] = powf(2.0f, > (float)(s->target_level - s->dialog_normalization[i])/6.0f); > } > - s->compression_exists[i] = get_bits1(gbc); > - if (s->compression_exists[i]) { > - s->heavy_dynamic_range[i] = AC3_HEAVY_RANGE(get_bits(gbc, 8)); > + if (hdr->compression_exists[i]) { > + s->heavy_dynamic_range[i] = AC3_HEAVY_RANGE(hdr->heavy_dynamic_range[i]); > } > } > > - /* dependent stream channel map */ > - if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) { > - if (get_bits1(gbc)) { > - int64_t channel_layout = 0; > - int channel_map = get_bits(gbc, 16); > - av_log(s->avctx, AV_LOG_DEBUG, "channel_map: %0X\n", channel_map); > - > - for (i = 0; i < 16; i++) > - if (channel_map & (1 << (EAC3_MAX_CHANNELS - i - 1))) > - channel_layout |= ff_eac3_custom_channel_map_locations[i][1]; > - > - if (av_popcount64(channel_layout) > EAC3_MAX_CHANNELS) { > - return AVERROR_INVALIDDATA; > - } > - s->channel_map = channel_map; > - } > - } > + s->channel_map = hdr->channel_map; > > /* mixing metadata */ > - if (get_bits1(gbc)) { > - /* center and surround mix levels */ > - if (s->channel_mode > AC3_CHMODE_STEREO) { > - s->preferred_downmix = get_bits(gbc, 2); > - if (s->channel_mode & 1) { > - /* if three front channels exist */ > - s->center_mix_level_ltrt = get_bits(gbc, 3); > - s->center_mix_level = get_bits(gbc, 3); > - } > - if (s->channel_mode & 4) { > - /* if a surround channel exists */ > - s->surround_mix_level_ltrt = av_clip(get_bits(gbc, 3), 3, 7); > - s->surround_mix_level = av_clip(get_bits(gbc, 3), 3, 7); > - } > - } > - > - /* lfe mix level */ > - if (s->lfe_on && (s->lfe_mix_level_exists = get_bits1(gbc))) { > - s->lfe_mix_level = get_bits(gbc, 5); > - } > - > - /* info for mixing with other streams and substreams */ > - if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT) { > - for (i = 0; i < (s->channel_mode ? 1 : 2); i++) { > - // TODO: apply program scale factor > - if (get_bits1(gbc)) { > - skip_bits(gbc, 6); // skip program scale factor > - } > - } > - if (get_bits1(gbc)) { > - skip_bits(gbc, 6); // skip external program scale factor > - } > - /* skip mixing parameter data */ > - switch(get_bits(gbc, 2)) { > - case 1: skip_bits(gbc, 5); break; > - case 2: skip_bits(gbc, 12); break; > - case 3: { > - int mix_data_size = (get_bits(gbc, 5) + 2) << 3; > - skip_bits_long(gbc, mix_data_size); > - break; > - } > - } > - /* skip pan information for mono or dual mono source */ > - if (s->channel_mode < AC3_CHMODE_STEREO) { > - for (i = 0; i < (s->channel_mode ? 1 : 2); i++) { > - if (get_bits1(gbc)) { > - /* note: this is not in the ATSC A/52B specification > - reference: ETSI TS 102 366 V1.1.1 > - section: E.1.3.1.25 */ > - skip_bits(gbc, 8); // skip pan mean direction index > - skip_bits(gbc, 6); // skip reserved paninfo bits > - } > - } > - } > - /* skip mixing configuration information */ > - if (get_bits1(gbc)) { > - for (blk = 0; blk < s->num_blocks; blk++) { > - if (s->num_blocks == 1 || get_bits1(gbc)) { > - skip_bits(gbc, 5); > - } > - } > - } > - } > - } > + s->preferred_downmix = hdr->preferred_downmix; > + s->center_mix_level_ltrt = hdr->center_mix_level_ltrt; > + s->center_mix_level = hdr->center_mix_level; > + s->surround_mix_level_ltrt = hdr->surround_mix_level_ltrt; > + s->surround_mix_level = hdr->surround_mix_level; > + s->lfe_mix_level_exists = hdr->lfe_mix_level_exists; > + s->lfe_mix_level = hdr->lfe_mix_level; > + s->dolby_surround_mode = hdr->dolby_surround_mode; > + s->dolby_headphone_mode = hdr->dolby_headphone_mode; > + s->dolby_surround_ex_mode = hdr->dolby_surround_ex_mode; > > /* informational metadata */ > - if (get_bits1(gbc)) { > - s->bitstream_mode = get_bits(gbc, 3); > - skip_bits(gbc, 2); // skip copyright bit and original bitstream bit > - if (s->channel_mode == AC3_CHMODE_STEREO) { > - s->dolby_surround_mode = get_bits(gbc, 2); > - s->dolby_headphone_mode = get_bits(gbc, 2); > - } > - if (s->channel_mode >= AC3_CHMODE_2F2R) { > - s->dolby_surround_ex_mode = get_bits(gbc, 2); > - } > - for (i = 0; i < (s->channel_mode ? 1 : 2); i++) { > - if (get_bits1(gbc)) { > - skip_bits(gbc, 8); // skip mix level, room type, and A/D converter type > - } > - } > - if (s->bit_alloc_params.sr_code != EAC3_SR_CODE_REDUCED) { > - skip_bits1(gbc); // skip source sample rate code > - } > - } > - > - /* converter synchronization flag > - If frames are less than six blocks, this bit should be turned on > - once every 6 blocks to indicate the start of a frame set. > - reference: RFC 4598, Section 2.1.3 Frame Sets */ > - if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT && s->num_blocks != 6) { > - skip_bits1(gbc); // skip converter synchronization flag > - } > - > - /* original frame size code if this stream was converted from AC-3 */ > - if (s->frame_type == EAC3_FRAME_TYPE_AC3_CONVERT && > - (s->num_blocks == 6 || get_bits1(gbc))) { > - skip_bits(gbc, 6); // skip frame size code > - } > + s->bitstream_mode = hdr->bitstream_mode; > > /* additional bitstream info */ > - if (get_bits1(gbc)) { > - int addbsil = get_bits(gbc, 6); > - for (i = 0; i < addbsil + 1; i++) { > - if (i == 0) { > - /* In this 8 bit chunk, the LSB is equal to flag_ec3_extension_type_a > - which can be used to detect Atmos presence */ > - skip_bits(gbc, 7); > - if (get_bits1(gbc)) { > - s->eac3_extension_type_a = 1; > - } > - } else { > - skip_bits(gbc, 8); // skip additional bit stream info > - } > - } > - } > + s->eac3_extension_type_a = hdr->eac3_extension_type_a; > > /* audio frame syntax flags, strategy data, and per-frame data */ > Seems like av_ac3_parse_header() simply presumes the buffer to be padded (like av_adts_header_parse() until 6c812a80ddfadb), although this is not a documented requirement. Your patch will make it worse, because it parses more. - Andreas _______________________________________________ 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".